diff --git a/spdy/core/spdy_deframer_visitor.cc b/spdy/core/spdy_deframer_visitor.cc
deleted file mode 100644
index 835fea9..0000000
--- a/spdy/core/spdy_deframer_visitor.cc
+++ /dev/null
@@ -1,1031 +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 "net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h"
-
-#include <stdlib.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
-#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
-#include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
-#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_flags.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
-
-using ::testing::AssertionFailure;
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-
-namespace spdy {
-namespace test {
-
-// Specify whether to process headers as request or response in visitor-related
-// params.
-enum class HeaderDirection { REQUEST, RESPONSE };
-
-// Types of HTTP/2 frames, per RFC 7540.
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-enum Http2FrameType {
-  DATA = 0,
-  HEADERS = 1,
-  PRIORITY = 2,
-  RST_STREAM = 3,
-  SETTINGS = 4,
-  PUSH_PROMISE = 5,
-  PING = 6,
-  GOAWAY = 7,
-  WINDOW_UPDATE = 8,
-  CONTINUATION = 9,
-  ALTSVC = 10,
-
-  // Not a frame type.
-  UNSET = -1,
-  UNKNOWN = -2,
-};
-
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-const char* Http2FrameTypeToString(Http2FrameType v) {
-  switch (v) {
-    case DATA:
-      return "DATA";
-    case HEADERS:
-      return "HEADERS";
-    case PRIORITY:
-      return "PRIORITY";
-    case RST_STREAM:
-      return "RST_STREAM";
-    case SETTINGS:
-      return "SETTINGS";
-    case PUSH_PROMISE:
-      return "PUSH_PROMISE";
-    case PING:
-      return "PING";
-    case GOAWAY:
-      return "GOAWAY";
-    case WINDOW_UPDATE:
-      return "WINDOW_UPDATE";
-    case CONTINUATION:
-      return "CONTINUATION";
-    case ALTSVC:
-      return "ALTSVC";
-    case UNSET:
-      return "UNSET";
-    case UNKNOWN:
-      return "UNKNOWN";
-    default:
-      return "Invalid Http2FrameType";
-  }
-}
-
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-inline std::ostream& operator<<(std::ostream& out, Http2FrameType v) {
-  return out << Http2FrameTypeToString(v);
-}
-
-// Flag bits in the flag field of the common header of HTTP/2 frames
-// (see https://httpwg.github.io/specs/rfc7540.html#FrameHeader for details on
-// the fixed 9-octet header structure shared by all frames).
-// Flag bits are only valid for specified frame types.
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-enum Http2HeaderFlag {
-  NO_FLAGS = 0,
-
-  END_STREAM_FLAG = 0x1,
-  ACK_FLAG = 0x1,
-  END_HEADERS_FLAG = 0x4,
-  PADDED_FLAG = 0x8,
-  PRIORITY_FLAG = 0x20,
-};
-
-// Returns name of frame type.
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-const char* Http2FrameTypeToString(Http2FrameType v);
-
-void SpdyDeframerVisitorInterface::OnPingAck(
-    std::unique_ptr<SpdyPingIR> frame) {
-  OnPing(std::move(frame));
-}
-
-void SpdyDeframerVisitorInterface::OnSettingsAck(
-    std::unique_ptr<SpdySettingsIR> frame) {
-  OnSettings(std::move(frame), nullptr);
-}
-
-class SpdyTestDeframerImpl : public SpdyTestDeframer,
-                             public SpdyHeadersHandlerInterface {
- public:
-  explicit SpdyTestDeframerImpl(
-      std::unique_ptr<SpdyDeframerVisitorInterface> listener)
-      : listener_(std::move(listener)) {
-    CHECK(listener_ != nullptr);
-  }
-  SpdyTestDeframerImpl(const SpdyTestDeframerImpl&) = delete;
-  SpdyTestDeframerImpl& operator=(const SpdyTestDeframerImpl&) = delete;
-  ~SpdyTestDeframerImpl() override = default;
-
-  bool AtFrameEnd() override;
-
-  // Callbacks defined in SpdyFramerVisitorInterface.  These are in the
-  // alphabetical order for ease of navigation, and are not in same order
-  // as in SpdyFramerVisitorInterface.
-  void OnAltSvc(SpdyStreamId stream_id,
-                absl::string_view origin,
-                const SpdyAltSvcWireFormat::AlternativeServiceVector&
-                    altsvc_vector) override;
-  void OnContinuation(SpdyStreamId stream_id, bool end) 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 OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
-               std::string detailed_error) 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 OnPing(SpdyPingId unique_id, bool is_ack) override;
-  void OnPriority(SpdyStreamId stream_id,
-                  SpdyStreamId parent_stream_id,
-                  int weight,
-                  bool exclusive) override;
-  void OnPushPromise(SpdyStreamId stream_id,
-                     SpdyStreamId promised_stream_id,
-                     bool end) override;
-  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
-  void OnSetting(SpdySettingsId id, uint32_t value) override;
-  void OnSettings() override;
-  void OnSettingsAck() override;
-  void OnSettingsEnd() 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;
-  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
-  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
-
-  // Callbacks defined in SpdyHeadersHandlerInterface.
-
-  void OnHeaderBlockStart() override;
-  void OnHeader(absl::string_view key, absl::string_view value) override;
-  void OnHeaderBlockEnd(size_t header_bytes_parsed,
-                        size_t compressed_header_bytes_parsed) override;
-
- protected:
-  void AtDataEnd();
-  void AtGoAwayEnd();
-  void AtHeadersEnd();
-  void AtPushPromiseEnd();
-
-  // Per-physical frame state.
-  // Frame type of the frame currently being processed.
-  Http2FrameType frame_type_ = UNSET;
-  // Stream id of the frame currently being processed.
-  SpdyStreamId stream_id_;
-  // Did the most recent frame header include the END_HEADERS flag?
-  bool end_ = false;
-  // Did the most recent frame header include the ack flag?
-  bool ack_ = false;
-
-  // Per-HPACK block state. Only valid while processing a HEADERS or
-  // PUSH_PROMISE frame, and its CONTINUATION frames.
-  // Did the most recent HEADERS or PUSH_PROMISE include the END_STREAM flag?
-  // Note that this does not necessarily indicate that the current frame is
-  // the last frame for the stream (may be followed by CONTINUATION frames,
-  // may only half close).
-  bool fin_ = false;
-  bool got_hpack_end_ = false;
-
-  std::unique_ptr<std::string> data_;
-
-  // Total length of the data frame.
-  size_t data_len_ = 0;
-
-  // Amount of skipped padding (i.e. total length of padding, including Pad
-  // Length field).
-  size_t padding_len_ = 0;
-
-  std::unique_ptr<std::string> goaway_description_;
-  std::unique_ptr<StringPairVector> headers_;
-  std::unique_ptr<SettingVector> settings_;
-  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
-
-  std::unique_ptr<SpdyGoAwayIR> goaway_ir_;
-  std::unique_ptr<SpdyHeadersIR> headers_ir_;
-  std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_;
-  std::unique_ptr<SpdySettingsIR> settings_ir_;
-
- private:
-  std::unique_ptr<SpdyDeframerVisitorInterface> listener_;
-};
-
-// static
-std::unique_ptr<SpdyTestDeframer> SpdyTestDeframer::CreateConverter(
-    std::unique_ptr<SpdyDeframerVisitorInterface> listener) {
-  return std::make_unique<SpdyTestDeframerImpl>(std::move(listener));
-}
-
-void SpdyTestDeframerImpl::AtDataEnd() {
-  SPDY_DVLOG(1) << "AtDataEnd";
-  CHECK_EQ(data_len_, padding_len_ + data_->size());
-  auto ptr = std::make_unique<SpdyDataIR>(stream_id_, std::move(*data_));
-  CHECK_EQ(0u, data_->size());
-  data_.reset();
-
-  CHECK_LE(0u, padding_len_);
-  CHECK_LE(padding_len_, 256u);
-  if (padding_len_ > 0) {
-    ptr->set_padding_len(padding_len_);
-  }
-  padding_len_ = 0;
-
-  ptr->set_fin(fin_);
-  listener_->OnData(std::move(ptr));
-  frame_type_ = UNSET;
-  fin_ = false;
-  data_len_ = 0;
-}
-
-void SpdyTestDeframerImpl::AtGoAwayEnd() {
-  SPDY_DVLOG(1) << "AtDataEnd";
-  CHECK_EQ(frame_type_, GOAWAY);
-  if (HTTP2_DIE_IF_NULL(goaway_description_)->empty()) {
-    listener_->OnGoAway(std::move(goaway_ir_));
-  } else {
-    listener_->OnGoAway(std::make_unique<SpdyGoAwayIR>(
-        goaway_ir_->last_good_stream_id(), goaway_ir_->error_code(),
-        std::move(*goaway_description_)));
-    CHECK_EQ(0u, goaway_description_->size());
-  }
-  goaway_description_.reset();
-  goaway_ir_.reset();
-  frame_type_ = UNSET;
-}
-
-void SpdyTestDeframerImpl::AtHeadersEnd() {
-  SPDY_DVLOG(1) << "AtDataEnd";
-  CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(end_) << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(got_hpack_end_);
-
-  CHECK(headers_ir_ != nullptr);
-  CHECK(headers_ != nullptr);
-  CHECK(headers_handler_ != nullptr);
-
-  CHECK_LE(0u, padding_len_);
-  CHECK_LE(padding_len_, 256u);
-  if (padding_len_ > 0) {
-    headers_ir_->set_padding_len(padding_len_);
-  }
-  padding_len_ = 0;
-
-  headers_ir_->set_header_block(headers_handler_->decoded_block().Clone());
-  headers_handler_.reset();
-  listener_->OnHeaders(std::move(headers_ir_), std::move(headers_));
-
-  frame_type_ = UNSET;
-  fin_ = false;
-  end_ = false;
-  got_hpack_end_ = false;
-}
-
-void SpdyTestDeframerImpl::AtPushPromiseEnd() {
-  SPDY_DVLOG(1) << "AtDataEnd";
-  CHECK(frame_type_ == PUSH_PROMISE || frame_type_ == CONTINUATION)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(end_) << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-
-  CHECK(push_promise_ir_ != nullptr);
-  CHECK(headers_ != nullptr);
-  CHECK(headers_handler_ != nullptr);
-
-  CHECK_EQ(headers_ir_.get(), nullptr);
-
-  CHECK_LE(0u, padding_len_);
-  CHECK_LE(padding_len_, 256u);
-  if (padding_len_ > 0) {
-    push_promise_ir_->set_padding_len(padding_len_);
-  }
-  padding_len_ = 0;
-
-  push_promise_ir_->set_header_block(headers_handler_->decoded_block().Clone());
-  headers_handler_.reset();
-  listener_->OnPushPromise(std::move(push_promise_ir_), std::move(headers_));
-
-  frame_type_ = UNSET;
-  end_ = false;
-}
-
-bool SpdyTestDeframerImpl::AtFrameEnd() {
-  bool incomplete_logical_header = false;
-  // The caller says that the SpdyFrame has reached the end of the frame,
-  // so if we have any accumulated data, flush it.
-  switch (frame_type_) {
-    case DATA:
-      AtDataEnd();
-      break;
-
-    case GOAWAY:
-      AtGoAwayEnd();
-      break;
-
-    case HEADERS:
-      if (end_) {
-        AtHeadersEnd();
-      } else {
-        incomplete_logical_header = true;
-      }
-      break;
-
-    case PUSH_PROMISE:
-      if (end_) {
-        AtPushPromiseEnd();
-      } else {
-        incomplete_logical_header = true;
-      }
-      break;
-
-    case CONTINUATION:
-      if (end_) {
-        if (headers_ir_) {
-          AtHeadersEnd();
-        } else if (push_promise_ir_) {
-          AtPushPromiseEnd();
-        } else {
-          SPDY_LOG(FATAL) << "Where is the SpdyFrameIR for the headers!";
-        }
-      } else {
-        incomplete_logical_header = true;
-      }
-      break;
-
-    case UNSET:
-      // Except for the frame types above, the others don't leave any record
-      // in the state of this object. Make sure nothing got left by accident.
-      CHECK_EQ(data_.get(), nullptr);
-      CHECK_EQ(goaway_description_.get(), nullptr);
-      CHECK_EQ(goaway_ir_.get(), nullptr);
-      CHECK_EQ(headers_.get(), nullptr);
-      CHECK_EQ(headers_handler_.get(), nullptr);
-      CHECK_EQ(headers_ir_.get(), nullptr);
-      CHECK_EQ(push_promise_ir_.get(), nullptr);
-      CHECK_EQ(settings_.get(), nullptr);
-      CHECK_EQ(settings_ir_.get(), nullptr);
-      break;
-
-    default:
-      SPDY_BUG << "Expected UNSET, instead frame_type_==" << frame_type_;
-      return false;
-  }
-  frame_type_ = UNSET;
-  stream_id_ = 0;
-  end_ = false;
-  ack_ = false;
-  if (!incomplete_logical_header) {
-    fin_ = false;
-  }
-  return true;
-}
-
-// Overridden methods from SpdyFramerVisitorInterface in alpha order...
-
-void SpdyTestDeframerImpl::OnAltSvc(
-    SpdyStreamId stream_id,
-    absl::string_view origin,
-    const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
-  SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-  auto ptr = std::make_unique<SpdyAltSvcIR>(stream_id);
-  ptr->set_origin(std::string(origin));
-  for (auto& altsvc : altsvc_vector) {
-    ptr->add_altsvc(altsvc);
-  }
-  listener_->OnAltSvc(std::move(ptr));
-}
-
-// A CONTINUATION frame contains a Header Block Fragment, and immediately
-// follows another frame that contains a Header Block Fragment (HEADERS,
-// PUSH_PROMISE or CONTINUATION). The last such frame has the END flag set.
-// SpdyFramer ensures that the behavior is correct before calling the visitor.
-void SpdyTestDeframerImpl::OnContinuation(SpdyStreamId stream_id, bool end) {
-  SPDY_DVLOG(1) << "OnContinuation stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-  CHECK_NE(nullptr, headers_.get());
-  frame_type_ = CONTINUATION;
-
-  stream_id_ = stream_id;
-  end_ = end;
-}
-
-// Note that length includes the padding length (0 to 256, when the optional
-// padding length field is counted). Padding comes after the payload, both
-// for DATA frames and for control frames.
-void SpdyTestDeframerImpl::OnDataFrameHeader(SpdyStreamId stream_id,
-                                             size_t length,
-                                             bool fin) {
-  SPDY_DVLOG(1) << "OnDataFrameHeader stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-  CHECK_EQ(data_.get(), nullptr);
-  frame_type_ = DATA;
-
-  stream_id_ = stream_id;
-  fin_ = fin;
-  data_len_ = length;
-  data_ = std::make_unique<std::string>();
-}
-
-// The SpdyFramer will not process any more data at this point.
-void SpdyTestDeframerImpl::OnError(
-    http2::Http2DecoderAdapter::SpdyFramerError error,
-    std::string /*detailed_error*/) {
-  SPDY_DVLOG(1) << "SpdyFramer detected an error in the stream: "
-                << http2::Http2DecoderAdapter::SpdyFramerErrorToString(error)
-                << "     frame_type_: " << Http2FrameTypeToString(frame_type_);
-  listener_->OnError(error, this);
-}
-
-// Received a GOAWAY frame from the peer. The last stream id it accepted from us
-// is |last_accepted_stream_id|. |status| is a protocol defined error code.
-// The frame may also contain data. After this OnGoAwayFrameData will be called
-// for any non-zero amount of data, and after that it will be called with len==0
-// to indicate the end of the GOAWAY frame.
-void SpdyTestDeframerImpl::OnGoAway(SpdyStreamId last_accepted_stream_id,
-                                    SpdyErrorCode error_code) {
-  SPDY_DVLOG(1) << "OnGoAway last_accepted_stream_id: "
-                << last_accepted_stream_id << "     error code: " << error_code;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  frame_type_ = GOAWAY;
-  goaway_ir_ =
-      std::make_unique<SpdyGoAwayIR>(last_accepted_stream_id, error_code, "");
-  goaway_description_ = std::make_unique<std::string>();
-}
-
-// If len==0 then we've reached the end of the GOAWAY frame.
-bool SpdyTestDeframerImpl::OnGoAwayFrameData(const char* goaway_data,
-                                             size_t len) {
-  SPDY_DVLOG(1) << "OnGoAwayFrameData";
-  CHECK_EQ(frame_type_, GOAWAY)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(goaway_description_ != nullptr);
-  goaway_description_->append(goaway_data, len);
-  return true;
-}
-
-SpdyHeadersHandlerInterface* SpdyTestDeframerImpl::OnHeaderFrameStart(
-    SpdyStreamId /*stream_id*/) {
-  return this;
-}
-
-void SpdyTestDeframerImpl::OnHeaderFrameEnd(SpdyStreamId stream_id) {
-  SPDY_DVLOG(1) << "OnHeaderFrameEnd stream_id: " << stream_id;
-}
-
-// Received the fixed portion of a HEADERS frame. Called before the variable
-// length (including zero length) Header Block Fragment is processed. If fin
-// is true then there will be no DATA or trailing HEADERS after this HEADERS
-// frame.
-// If end is true, then there will be no CONTINUATION frame(s) following this
-// frame; else if true then there will be CONTINATION frames(s) immediately
-// following this frame, terminated by a CONTINUATION frame with end==true.
-void SpdyTestDeframerImpl::OnHeaders(SpdyStreamId stream_id,
-                                     bool has_priority,
-                                     int weight,
-                                     SpdyStreamId parent_stream_id,
-                                     bool exclusive,
-                                     bool fin,
-                                     bool end) {
-  SPDY_DVLOG(1) << "OnHeaders stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-  frame_type_ = HEADERS;
-
-  stream_id_ = stream_id;
-  fin_ = fin;
-  end_ = end;
-
-  headers_ = std::make_unique<StringPairVector>();
-  headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-  headers_ir_ = std::make_unique<SpdyHeadersIR>(stream_id);
-  headers_ir_->set_fin(fin);
-  if (has_priority) {
-    headers_ir_->set_has_priority(true);
-    headers_ir_->set_weight(weight);
-    headers_ir_->set_parent_stream_id(parent_stream_id);
-    headers_ir_->set_exclusive(exclusive);
-  }
-}
-
-// The HTTP/2 protocol refers to the payload, |unique_id| here, as 8 octets of
-// opaque data that is to be echoed back to the sender, with the ACK bit added.
-// It isn't defined as a counter,
-// or frame id, as the SpdyPingId naming might imply.
-// Responding to a PING is supposed to be at the highest priority.
-void SpdyTestDeframerImpl::OnPing(uint64_t unique_id, bool is_ack) {
-  SPDY_DVLOG(1) << "OnPing unique_id: " << unique_id
-                << "      is_ack: " << (is_ack ? "true" : "false");
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  auto ptr = std::make_unique<SpdyPingIR>(unique_id);
-  if (is_ack) {
-    ptr->set_is_ack(is_ack);
-    listener_->OnPingAck(std::move(ptr));
-  } else {
-    listener_->OnPing(std::move(ptr));
-  }
-}
-
-void SpdyTestDeframerImpl::OnPriority(SpdyStreamId stream_id,
-                                      SpdyStreamId parent_stream_id,
-                                      int weight,
-                                      bool exclusive) {
-  SPDY_DVLOG(1) << "OnPriority stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-
-  listener_->OnPriority(std::make_unique<SpdyPriorityIR>(
-      stream_id, parent_stream_id, weight, exclusive));
-}
-
-void SpdyTestDeframerImpl::OnPushPromise(SpdyStreamId stream_id,
-                                         SpdyStreamId promised_stream_id,
-                                         bool end) {
-  SPDY_DVLOG(1) << "OnPushPromise stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-
-  frame_type_ = PUSH_PROMISE;
-  stream_id_ = stream_id;
-  end_ = end;
-
-  headers_ = std::make_unique<StringPairVector>();
-  headers_handler_ = std::make_unique<RecordingHeadersHandler>();
-  push_promise_ir_ =
-      std::make_unique<SpdyPushPromiseIR>(stream_id, promised_stream_id);
-}
-
-// Closes the specified stream. After this the sender may still send PRIORITY
-// frames for this stream, which we can ignore.
-void SpdyTestDeframerImpl::OnRstStream(SpdyStreamId stream_id,
-                                       SpdyErrorCode error_code) {
-  SPDY_DVLOG(1) << "OnRstStream stream_id: " << stream_id
-                << "     error code: " << error_code;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_GT(stream_id, 0u);
-
-  listener_->OnRstStream(
-      std::make_unique<SpdyRstStreamIR>(stream_id, error_code));
-}
-
-// Called for an individual setting. There is no negotiation; the sender is
-// stating the value that the sender is using.
-void SpdyTestDeframerImpl::OnSetting(SpdySettingsId id, uint32_t value) {
-  SPDY_DVLOG(1) << "OnSetting id: " << id << std::hex << "    value: " << value;
-  CHECK_EQ(frame_type_, SETTINGS)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(settings_ != nullptr);
-  SpdyKnownSettingsId known_id;
-  if (ParseSettingsId(id, &known_id)) {
-    settings_->push_back(std::make_pair(known_id, value));
-    settings_ir_->AddSetting(known_id, value);
-  }
-}
-
-// Called at the start of a SETTINGS frame with setting entries, but not the
-// (required) ACK of a SETTINGS frame. There is no stream_id because
-// the settings apply to the entire connection, not to an individual stream.
-void SpdyTestDeframerImpl::OnSettings() {
-  SPDY_DVLOG(1) << "OnSettings";
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_EQ(nullptr, settings_ir_.get());
-  CHECK_EQ(nullptr, settings_.get());
-  frame_type_ = SETTINGS;
-  ack_ = false;
-
-  settings_ = std::make_unique<SettingVector>();
-  settings_ir_ = std::make_unique<SpdySettingsIR>();
-}
-
-void SpdyTestDeframerImpl::OnSettingsAck() {
-  SPDY_DVLOG(1) << "OnSettingsAck";
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  auto ptr = std::make_unique<SpdySettingsIR>();
-  ptr->set_is_ack(true);
-  listener_->OnSettingsAck(std::move(ptr));
-}
-
-void SpdyTestDeframerImpl::OnSettingsEnd() {
-  SPDY_DVLOG(1) << "OnSettingsEnd";
-  CHECK_EQ(frame_type_, SETTINGS)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(!ack_);
-  CHECK_NE(nullptr, settings_ir_.get());
-  CHECK_NE(nullptr, settings_.get());
-  listener_->OnSettings(std::move(settings_ir_), std::move(settings_));
-  frame_type_ = UNSET;
-}
-
-// Called for a zero length DATA frame with the END_STREAM flag set, or at the
-// end a complete HPACK block (and its padding) that started with a HEADERS
-// frame with the END_STREAM flag set. Doesn't apply to PUSH_PROMISE frames
-// because they don't have END_STREAM flags.
-void SpdyTestDeframerImpl::OnStreamEnd(SpdyStreamId stream_id) {
-  SPDY_DVLOG(1) << "OnStreamEnd stream_id: " << stream_id;
-  CHECK_EQ(stream_id_, stream_id);
-  CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
-        frame_type_ == CONTINUATION)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(fin_);
-}
-
-// The data arg points into the non-padding payload of a DATA frame.
-// This must be a DATA frame (i.e. this method will not be
-// called for HEADERS or CONTINUATION frames).
-// This method may be called multiple times for a single DATA frame, depending
-// upon buffer boundaries.
-void SpdyTestDeframerImpl::OnStreamFrameData(SpdyStreamId stream_id,
-                                             const char* data,
-                                             size_t len) {
-  SPDY_DVLOG(1) << "OnStreamFrameData stream_id: " << stream_id
-                << "    len: " << len;
-  CHECK_EQ(stream_id_, stream_id);
-  CHECK_EQ(frame_type_, DATA);
-  data_->append(data, len);
-}
-
-// Called when receiving the padding length field at the start of the DATA frame
-// payload. value will be in the range 0 to 255.
-void SpdyTestDeframerImpl::OnStreamPadLength(SpdyStreamId stream_id,
-                                             size_t value) {
-  SPDY_DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
-                << "    value: " << value;
-  CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
-        frame_type_ == PUSH_PROMISE)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_EQ(stream_id_, stream_id);
-  CHECK_GE(255u, value);
-  // Count the padding length byte against total padding.
-  padding_len_ += 1;
-  CHECK_EQ(1u, padding_len_);
-}
-
-// Called when padding is skipped over at the end of the DATA frame. len will
-// be in the range 1 to 255.
-void SpdyTestDeframerImpl::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
-  SPDY_DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
-                << "    len: " << len;
-  CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
-        frame_type_ == PUSH_PROMISE)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_EQ(stream_id_, stream_id);
-  CHECK_LE(1u, len);
-  CHECK_GE(255u, len);
-  padding_len_ += len;
-  CHECK_LE(padding_len_, 256u) << "len=" << len;
-}
-
-// WINDOW_UPDATE is supposed to be hop-by-hop, according to the spec.
-// stream_id is 0 if the update applies to the connection, else stream_id
-// will be the id of a stream previously seen, which maybe half or fully
-// closed.
-void SpdyTestDeframerImpl::OnWindowUpdate(SpdyStreamId stream_id,
-                                          int delta_window_size) {
-  SPDY_DVLOG(1) << "OnWindowUpdate stream_id: " << stream_id
-                << "    delta_window_size: " << delta_window_size;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK_NE(0, delta_window_size);
-
-  listener_->OnWindowUpdate(
-      std::make_unique<SpdyWindowUpdateIR>(stream_id, delta_window_size));
-}
-
-// Return true to indicate that the stream_id is valid; if not valid then
-// SpdyFramer considers the connection corrupted. Requires keeping track
-// of the set of currently open streams. For now we'll assume that unknown
-// frame types are unsupported.
-bool SpdyTestDeframerImpl::OnUnknownFrame(SpdyStreamId stream_id,
-                                          uint8_t /*frame_type*/) {
-  SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
-  CHECK_EQ(frame_type_, UNSET)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  frame_type_ = UNKNOWN;
-
-  stream_id_ = stream_id;
-  return false;
-}
-
-// Callbacks defined in SpdyHeadersHandlerInterface.
-
-void SpdyTestDeframerImpl::OnHeaderBlockStart() {
-  CHECK(frame_type_ == HEADERS || frame_type_ == PUSH_PROMISE)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(headers_ != nullptr);
-  CHECK_EQ(0u, headers_->size());
-  got_hpack_end_ = false;
-}
-
-void SpdyTestDeframerImpl::OnHeader(absl::string_view key,
-                                    absl::string_view value) {
-  CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
-        frame_type_ == PUSH_PROMISE)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(!got_hpack_end_);
-  HTTP2_DIE_IF_NULL(headers_)->emplace_back(std::string(key),
-                                            std::string(value));
-  HTTP2_DIE_IF_NULL(headers_handler_)->OnHeader(key, value);
-}
-
-void SpdyTestDeframerImpl::OnHeaderBlockEnd(
-    size_t /* header_bytes_parsed */,
-    size_t /* compressed_header_bytes_parsed */) {
-  CHECK(headers_ != nullptr);
-  CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
-        frame_type_ == PUSH_PROMISE)
-      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
-  CHECK(end_);
-  CHECK(!got_hpack_end_);
-  got_hpack_end_ = true;
-}
-
-class LoggingSpdyDeframerDelegate : public SpdyDeframerVisitorInterface {
- public:
-  explicit LoggingSpdyDeframerDelegate(
-      std::unique_ptr<SpdyDeframerVisitorInterface> wrapped)
-      : wrapped_(std::move(wrapped)) {
-    if (!wrapped_) {
-      wrapped_ = std::make_unique<SpdyDeframerVisitorInterface>();
-    }
-  }
-  ~LoggingSpdyDeframerDelegate() override = default;
-
-  void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnAltSvc";
-    wrapped_->OnAltSvc(std::move(frame));
-  }
-  void OnData(std::unique_ptr<SpdyDataIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnData";
-    wrapped_->OnData(std::move(frame));
-  }
-  void OnGoAway(std::unique_ptr<SpdyGoAwayIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnGoAway";
-    wrapped_->OnGoAway(std::move(frame));
-  }
-
-  // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-  // significantly modifies the headers, so the actual header entries (name
-  // and value strings) are provided in a vector.
-  void OnHeaders(std::unique_ptr<SpdyHeadersIR> frame,
-                 std::unique_ptr<StringPairVector> headers) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnHeaders";
-    wrapped_->OnHeaders(std::move(frame), std::move(headers));
-  }
-
-  void OnPing(std::unique_ptr<SpdyPingIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPing";
-    wrapped_->OnPing(std::move(frame));
-  }
-  void OnPingAck(std::unique_ptr<SpdyPingIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPingAck";
-    wrapped_->OnPingAck(std::move(frame));
-  }
-
-  void OnPriority(std::unique_ptr<SpdyPriorityIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPriority";
-    wrapped_->OnPriority(std::move(frame));
-  }
-
-  // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-  // significantly modifies the headers, so the actual header entries (name
-  // and value strings) are provided in a vector.
-  void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> frame,
-                     std::unique_ptr<StringPairVector> headers) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPushPromise";
-    wrapped_->OnPushPromise(std::move(frame), std::move(headers));
-  }
-
-  void OnRstStream(std::unique_ptr<SpdyRstStreamIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnRstStream";
-    wrapped_->OnRstStream(std::move(frame));
-  }
-
-  // SpdySettingsIR has a map for settings, so loses info about the order of
-  // settings, and whether the same setting appeared more than once, so the
-  // the actual settings (parameter and value) are provided in a vector.
-  void OnSettings(std::unique_ptr<SpdySettingsIR> frame,
-                  std::unique_ptr<SettingVector> settings) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettings";
-    wrapped_->OnSettings(std::move(frame), std::move(settings));
-  }
-
-  // A settings frame with an ACK has no content, but for uniformity passing
-  // a frame with the ACK flag set.
-  void OnSettingsAck(std::unique_ptr<SpdySettingsIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettingsAck";
-    wrapped_->OnSettingsAck(std::move(frame));
-  }
-
-  void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> frame) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnWindowUpdate";
-    wrapped_->OnWindowUpdate(std::move(frame));
-  }
-
-  // The SpdyFramer will not process any more data at this point.
-  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
-               SpdyTestDeframer* deframer) override {
-    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnError";
-    wrapped_->OnError(error, deframer);
-  }
-
- private:
-  std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_;
-};
-
-// static
-std::unique_ptr<SpdyDeframerVisitorInterface>
-SpdyDeframerVisitorInterface::LogBeforeVisiting(
-    std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_listener) {
-  return std::make_unique<LoggingSpdyDeframerDelegate>(
-      std::move(wrapped_listener));
-}
-
-CollectedFrame::CollectedFrame() = default;
-
-CollectedFrame::CollectedFrame(CollectedFrame&& other)
-    : frame_ir(std::move(other.frame_ir)),
-      headers(std::move(other.headers)),
-      settings(std::move(other.settings)),
-      error_reported(other.error_reported) {}
-
-CollectedFrame::~CollectedFrame() = default;
-
-CollectedFrame& CollectedFrame::operator=(CollectedFrame&& other) {
-  frame_ir = std::move(other.frame_ir);
-  headers = std::move(other.headers);
-  settings = std::move(other.settings);
-  error_reported = other.error_reported;
-  return *this;
-}
-
-AssertionResult CollectedFrame::VerifyHasHeaders(
-    const StringPairVector& expected_headers) const {
-  VERIFY_NE(headers.get(), nullptr);
-  VERIFY_THAT(*headers, ::testing::ContainerEq(expected_headers));
-  return AssertionSuccess();
-}
-
-AssertionResult CollectedFrame::VerifyHasSettings(
-    const SettingVector& expected_settings) const {
-  VERIFY_NE(settings.get(), nullptr);
-  VERIFY_THAT(*settings, testing::ContainerEq(expected_settings));
-  return AssertionSuccess();
-}
-
-DeframerCallbackCollector::DeframerCallbackCollector(
-    std::vector<CollectedFrame>* collected_frames)
-    : collected_frames_(HTTP2_DIE_IF_NULL(collected_frames)) {}
-
-void DeframerCallbackCollector::OnAltSvc(
-    std::unique_ptr<SpdyAltSvcIR> frame_ir) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-void DeframerCallbackCollector::OnData(std::unique_ptr<SpdyDataIR> frame_ir) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-void DeframerCallbackCollector::OnGoAway(
-    std::unique_ptr<SpdyGoAwayIR> frame_ir) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-// SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-// significantly modifies the headers, so the actual header entries (name
-// and value strings) are provided in a vector.
-void DeframerCallbackCollector::OnHeaders(
-    std::unique_ptr<SpdyHeadersIR> frame_ir,
-    std::unique_ptr<StringPairVector> headers) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  cf.headers = std::move(headers);
-  collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnPing(std::unique_ptr<SpdyPingIR> frame_ir) {
-  EXPECT_TRUE(frame_ir && !frame_ir->is_ack());
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnPingAck(
-    std::unique_ptr<SpdyPingIR> frame_ir) {
-  EXPECT_TRUE(frame_ir && frame_ir->is_ack());
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnPriority(
-    std::unique_ptr<SpdyPriorityIR> frame_ir) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-// SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-// significantly modifies the headers, so the actual header entries (name
-// and value strings) are provided in a vector.
-void DeframerCallbackCollector::OnPushPromise(
-    std::unique_ptr<SpdyPushPromiseIR> frame_ir,
-    std::unique_ptr<StringPairVector> headers) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  cf.headers = std::move(headers);
-  collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnRstStream(
-    std::unique_ptr<SpdyRstStreamIR> frame_ir) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-// SpdySettingsIR has a map for settings, so loses info about the order of
-// settings, and whether the same setting appeared more than once, so the
-// the actual settings (parameter and value) are provided in a vector.
-void DeframerCallbackCollector::OnSettings(
-    std::unique_ptr<SpdySettingsIR> frame_ir,
-    std::unique_ptr<SettingVector> settings) {
-  EXPECT_TRUE(frame_ir && !frame_ir->is_ack());
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  cf.settings = std::move(settings);
-  collected_frames_->push_back(std::move(cf));
-}
-
-// A settings frame_ir with an ACK has no content, but for uniformity passing
-// a frame_ir with the ACK flag set.
-void DeframerCallbackCollector::OnSettingsAck(
-    std::unique_ptr<SpdySettingsIR> frame_ir) {
-  EXPECT_TRUE(frame_ir && frame_ir->is_ack());
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnWindowUpdate(
-    std::unique_ptr<SpdyWindowUpdateIR> frame_ir) {
-  CollectedFrame cf;
-  cf.frame_ir = std::move(frame_ir);
-  collected_frames_->push_back(std::move(cf));
-}
-
-// The SpdyFramer will not process any more data at this point.
-void DeframerCallbackCollector::OnError(
-    http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
-    SpdyTestDeframer* /*deframer*/) {
-  CollectedFrame cf;
-  cf.error_reported = true;
-  collected_frames_->push_back(std::move(cf));
-}
-
-}  // namespace test
-}  // namespace spdy
diff --git a/spdy/core/spdy_deframer_visitor.h b/spdy/core/spdy_deframer_visitor.h
deleted file mode 100644
index f17df98..0000000
--- a/spdy/core/spdy_deframer_visitor.h
+++ /dev/null
@@ -1,247 +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_DEFRAMER_VISITOR_H_
-#define QUICHE_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_
-
-// Supports testing by converting callbacks to SpdyFramerVisitorInterface into
-// callbacks to SpdyDeframerVisitorInterface, whose arguments are generally
-// SpdyFrameIR instances. This enables a test client or test backend to operate
-// at a level between the low-level callbacks of SpdyFramerVisitorInterface and
-// the much higher level of entire messages (i.e. headers, body, trailers).
-// Where possible the converter (SpdyTestDeframer) tries to preserve information
-// that might be useful to tests (e.g. the order of headers or the amount of
-// padding); the design also aims to allow tests to be concise, ideally
-// supporting gMock style EXPECT_CALL(visitor, OnHeaders(...matchers...))
-// without too much boilerplate.
-//
-// Only supports HTTP/2 for the moment.
-//
-// Example of usage:
-//
-//    SpdyFramer framer(HTTP2);
-//
-//    // Need to call SpdyTestDeframer::AtFrameEnd() after processing each
-//    // frame, so tell SpdyFramer to stop after each.
-//    framer.set_process_single_input_frame(true);
-//
-//    // Need the new OnHeader callbacks.
-//    framer.set_use_new_methods_for_test(true);
-//
-//    // Create your visitor, a subclass of SpdyDeframerVisitorInterface.
-//    // For example, using DeframerCallbackCollector to collect frames:
-//    std::vector<CollectedFrame> collected_frames;
-//    auto your_visitor = std::make_unique<DeframerCallbackCollector>(
-//        &collected_frames);
-//
-//    // Transfer ownership of your visitor to the converter, which ensures that
-//    // your visitor stays alive while the converter needs to call it.
-//    auto the_deframer = SpdyTestDeframer::CreateConverter(
-//       std::move(your_visitor));
-//
-//    // Tell the framer to notify SpdyTestDeframer of the decoded frame
-//    // details.
-//    framer.set_visitor(the_deframer.get());
-//
-//    // Process frames.
-//    absl::string_view input = ...
-//    while (!input.empty() && !framer.HasError()) {
-//      size_t consumed = framer.ProcessInput(input.data(), input.size());
-//      input.remove_prefix(consumed);
-//      if (framer.state() == SpdyFramer::SPDY_READY_FOR_FRAME) {
-//        the_deframer->AtFrameEnd();
-//      }
-//    }
-//
-//    // Make sure that the correct frames were received. For example:
-//    ASSERT_EQ(collected_frames.size(), 3);
-//
-//    SpdyDataIR expected1(7 /*stream_id*/, "Data Payload");
-//    expected1.set_padding_len(17);
-//    EXPECT_TRUE(collected_frames[0].VerifyEquals(expected1));
-//
-//    // Repeat for the other frames.
-//
-// Note that you could also seed the subclass of SpdyDeframerVisitorInterface
-// with the expected frames, which it would pop-off the list as its expectations
-// are met.
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
-
-namespace spdy {
-namespace test {
-
-// Non-lossy representation of a SETTINGS frame payload.
-typedef std::vector<std::pair<SpdyKnownSettingsId, uint32_t>> SettingVector;
-
-// StringPairVector is used to record information lost by SpdyHeaderBlock, in
-// particular the order of each header entry, though it doesn't expose the
-// inner details of the HPACK block, such as the type of encoding selected
-// for each header entry, nor dynamic table size changes.
-typedef std::pair<std::string, std::string> StringPair;
-typedef std::vector<StringPair> StringPairVector;
-
-// Forward decl.
-class SpdyTestDeframer;
-
-// Note that this only roughly captures the frames, as padding bytes are lost,
-// continuation frames are combined with their leading HEADERS or PUSH_PROMISE,
-// the details of the HPACK encoding are lost, leaving
-// only the list of header entries (name and value strings). If really helpful,
-// we could add a SpdyRawDeframerVisitorInterface that gets the HPACK bytes,
-// and receives continuation frames. For more info we'd need to improve
-// SpdyFramerVisitorInterface.
-class SpdyDeframerVisitorInterface {
- public:
-  virtual ~SpdyDeframerVisitorInterface() {}
-
-  // Wrap a visitor in another SpdyDeframerVisitorInterface that will
-  // DVLOG each call, and will then forward the calls to the wrapped visitor
-  // (if provided; nullptr is OK). Takes ownership of the wrapped visitor.
-  static std::unique_ptr<SpdyDeframerVisitorInterface> LogBeforeVisiting(
-      std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_visitor);
-
-  virtual void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> /*frame*/) {}
-  virtual void OnData(std::unique_ptr<SpdyDataIR> /*frame*/) {}
-  virtual void OnGoAway(std::unique_ptr<SpdyGoAwayIR> /*frame*/) {}
-
-  // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-  // significantly modifies the headers, so the actual header entries (name
-  // and value strings) are provided in a vector.
-  virtual void OnHeaders(std::unique_ptr<SpdyHeadersIR> /*frame*/,
-                         std::unique_ptr<StringPairVector> /*headers*/) {}
-
-  virtual void OnPing(std::unique_ptr<SpdyPingIR> /*frame*/) {}
-  virtual void OnPingAck(std::unique_ptr<SpdyPingIR> /*frame*/);
-  virtual void OnPriority(std::unique_ptr<SpdyPriorityIR> /*frame*/) {}
-
-  // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-  // significantly modifies the headers, so the actual header entries (name
-  // and value strings) are provided in a vector.
-  virtual void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> /*frame*/,
-                             std::unique_ptr<StringPairVector> /*headers*/) {}
-
-  virtual void OnRstStream(std::unique_ptr<SpdyRstStreamIR> /*frame*/) {}
-
-  // SpdySettingsIR has a map for settings, so loses info about the order of
-  // settings, and whether the same setting appeared more than once, so the
-  // the actual settings (parameter and value) are provided in a vector.
-  virtual void OnSettings(std::unique_ptr<SpdySettingsIR> /*frame*/,
-                          std::unique_ptr<SettingVector> /*settings*/) {}
-
-  // A settings frame with an ACK has no content, but for uniformity passing
-  // a frame with the ACK flag set.
-  virtual void OnSettingsAck(std::unique_ptr<SpdySettingsIR> /*frame*/);
-
-  virtual void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> /*frame*/) {}
-
-  // The SpdyFramer will not process any more data at this point.
-  virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
-                       SpdyTestDeframer* /*deframer*/) {}
-};
-
-class SpdyTestDeframer : public SpdyFramerVisitorInterface {
- public:
-  ~SpdyTestDeframer() override {}
-
-  // Creates a SpdyFramerVisitorInterface that builds SpdyFrameIR concrete
-  // instances based on the callbacks it receives; when an entire frame is
-  // decoded/reconstructed it calls the passed in SpdyDeframerVisitorInterface.
-  // Transfers ownership of visitor to the new SpdyTestDeframer, which ensures
-  // that it continues to exist while the SpdyTestDeframer exists.
-  static std::unique_ptr<SpdyTestDeframer> CreateConverter(
-      std::unique_ptr<SpdyDeframerVisitorInterface> visitor);
-
-  // Call to notify the deframer that the SpdyFramer has returned after reaching
-  // the end of decoding a frame. This is used to flush info about some frame
-  // types where we don't get a clear end signal; others are flushed (i.e. the
-  // appropriate call to the SpdyDeframerVisitorInterface method is invoked)
-  // as they're decoded by SpdyFramer and it calls the deframer. See the
-  // example in the comments at the top of this file.
-  virtual bool AtFrameEnd() = 0;
-
- protected:
-  SpdyTestDeframer() {}
-  SpdyTestDeframer(const SpdyTestDeframer&) = delete;
-  SpdyTestDeframer& operator=(const SpdyTestDeframer&) = delete;
-};
-
-// CollectedFrame holds the result of one call to SpdyDeframerVisitorInterface,
-// as recorded by DeframerCallbackCollector.
-struct CollectedFrame {
-  CollectedFrame();
-  CollectedFrame(CollectedFrame&& other);
-  ~CollectedFrame();
-  CollectedFrame& operator=(CollectedFrame&& other);
-
-  // Compare a SpdyFrameIR sub-class instance, expected_ir, against the
-  // collected SpdyFrameIR.
-  template <class T,
-            typename X =
-                typename std::enable_if<std::is_base_of<SpdyFrameIR, T>::value>>
-  ::testing::AssertionResult VerifyHasFrame(const T& expected_ir) const {
-    return VerifySpdyFrameIREquals(expected_ir, frame_ir.get());
-  }
-
-  // Compare the collected headers against a StringPairVector. Ignores
-  // this->frame_ir.
-  ::testing::AssertionResult VerifyHasHeaders(
-      const StringPairVector& expected_headers) const;
-
-  // Compare the collected settings (parameter and value pairs) against
-  // expected_settings. Ignores this->frame_ir.
-  ::testing::AssertionResult VerifyHasSettings(
-      const SettingVector& expected_settings) const;
-
-  std::unique_ptr<SpdyFrameIR> frame_ir;
-  std::unique_ptr<StringPairVector> headers;
-  std::unique_ptr<SettingVector> settings;
-  bool error_reported = false;
-};
-
-// Creates a CollectedFrame instance for each callback, storing it in the
-// vector provided to the constructor.
-class DeframerCallbackCollector : public SpdyDeframerVisitorInterface {
- public:
-  explicit DeframerCallbackCollector(
-      std::vector<CollectedFrame>* collected_frames);
-  ~DeframerCallbackCollector() override {}
-
-  void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame_ir) override;
-  void OnData(std::unique_ptr<SpdyDataIR> frame_ir) override;
-  void OnGoAway(std::unique_ptr<SpdyGoAwayIR> frame_ir) override;
-  void OnHeaders(std::unique_ptr<SpdyHeadersIR> frame_ir,
-                 std::unique_ptr<StringPairVector> headers) override;
-  void OnPing(std::unique_ptr<SpdyPingIR> frame_ir) override;
-  void OnPingAck(std::unique_ptr<SpdyPingIR> frame_ir) override;
-  void OnPriority(std::unique_ptr<SpdyPriorityIR> frame_ir) override;
-  void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> frame_ir,
-                     std::unique_ptr<StringPairVector> headers) override;
-  void OnRstStream(std::unique_ptr<SpdyRstStreamIR> frame_ir) override;
-  void OnSettings(std::unique_ptr<SpdySettingsIR> frame_ir,
-                  std::unique_ptr<SettingVector> settings) override;
-  void OnSettingsAck(std::unique_ptr<SpdySettingsIR> frame_ir) override;
-  void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> frame_ir) override;
-  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
-               SpdyTestDeframer* deframer) override;
-
- private:
-  std::vector<CollectedFrame>* collected_frames_;
-};
-
-}  // namespace test
-}  // namespace spdy
-
-#endif  // QUICHE_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_
diff --git a/spdy/core/spdy_deframer_visitor_test.cc b/spdy/core/spdy_deframer_visitor_test.cc
deleted file mode 100644
index b90d0b0..0000000
--- a/spdy/core/spdy_deframer_visitor_test.cc
+++ /dev/null
@@ -1,246 +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 "net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h"
-
-#include <stdlib.h>
-
-#include <algorithm>
-#include <limits>
-
-#include "net/third_party/quiche/src/http2/test_tools/http2_random.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
-#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
-#include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
-
-namespace spdy {
-namespace test {
-namespace {
-
-class SpdyDeframerVisitorTest : public QuicheTest {
- protected:
-  SpdyDeframerVisitorTest() : encoder_(SpdyFramer::ENABLE_COMPRESSION) {
-    decoder_.set_process_single_input_frame(true);
-    auto collector =
-        std::make_unique<DeframerCallbackCollector>(&collected_frames_);
-    auto log_and_collect =
-        SpdyDeframerVisitorInterface::LogBeforeVisiting(std::move(collector));
-    deframer_ = SpdyTestDeframer::CreateConverter(std::move(log_and_collect));
-    decoder_.set_visitor(deframer_.get());
-  }
-
-  bool DeframeInput(const char* input, size_t size) {
-    size_t input_remaining = size;
-    while (input_remaining > 0 &&
-           decoder_.spdy_framer_error() ==
-               http2::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 =
-          (random_.Uniform(std::min(input_remaining, kMaxReadSize))) + 1;
-      size_t bytes_processed = decoder_.ProcessInput(input, bytes_read);
-      input_remaining -= bytes_processed;
-      input += bytes_processed;
-      if (decoder_.state() ==
-          http2::Http2DecoderAdapter::SPDY_READY_FOR_FRAME) {
-        deframer_->AtFrameEnd();
-      }
-    }
-    return (input_remaining == 0 &&
-            decoder_.spdy_framer_error() ==
-                http2::Http2DecoderAdapter::SPDY_NO_ERROR);
-  }
-
-  SpdyFramer encoder_;
-  http2::Http2DecoderAdapter decoder_;
-  std::vector<CollectedFrame> collected_frames_;
-  std::unique_ptr<SpdyTestDeframer> deframer_;
-
- private:
-  http2::test::Http2Random random_;
-};
-
-TEST_F(SpdyDeframerVisitorTest, DataFrame) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x0d,        // Length = 13.
-      0x00,                    // DATA
-      0x08,                    // PADDED
-      0x00, 0x00, 0x00, 0x01,  // Stream 1
-      0x07,                    // Pad length field.
-      'h',  'e',  'l',  'l',   // Data
-      'o',                     // More Data
-      0x00, 0x00, 0x00, 0x00,  // Padding
-      0x00, 0x00, 0x00         // More Padding
-  };
-
-  EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
-  ASSERT_EQ(1u, collected_frames_.size());
-  const CollectedFrame& cf0 = collected_frames_[0];
-  ASSERT_NE(cf0.frame_ir, nullptr);
-
-  SpdyDataIR expected_ir(/* stream_id = */ 1, "hello");
-  expected_ir.set_padding_len(8);
-  EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-}
-
-TEST_F(SpdyDeframerVisitorTest, HeaderFrameWithContinuation) {
-  const char kFrameData[] = {
-      0x00, 0x00, 0x05,        // Payload Length: 5
-      0x01,                    // Type: HEADERS
-      0x09,                    // Flags: PADDED | END_STREAM
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x04,                    // Padding Length: 4
-      0x00, 0x00, 0x00, 0x00,  // Padding
-      /* Second Frame */
-      0x00, 0x00, 0x12,        // Payload Length: 18
-      0x09,                    // Type: CONTINUATION
-      0x04,                    // Flags: END_HEADERS
-      0x00, 0x00, 0x00, 0x01,  // Stream: 1
-      0x00,                    // Unindexed, literal name & value
-      0x03, 0x62, 0x61, 0x72,  // Name len and name (3, "bar")
-      0x03, 0x66, 0x6f, 0x6f,  // Value len and value (3, "foo")
-      0x00,                    // Unindexed, literal name & value
-      0x03, 0x66, 0x6f, 0x6f,  // Name len and name (3, "foo")
-      0x03, 0x62, 0x61, 0x72,  // Value len and value (3, "bar")
-  };
-
-  EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
-  ASSERT_EQ(1u, collected_frames_.size());
-  const CollectedFrame& cf0 = collected_frames_[0];
-
-  StringPairVector headers;
-  headers.push_back({"bar", "foo"});
-  headers.push_back({"foo", "bar"});
-
-  EXPECT_TRUE(cf0.VerifyHasHeaders(headers));
-
-  SpdyHeadersIR expected_ir(/* stream_id = */ 1);
-  // Yet again SpdyFramerVisitorInterface is lossy: it doesn't call OnPadding
-  // for HEADERS, just for DATA. Sigh.
-  //    expected_ir.set_padding_len(5);
-  expected_ir.set_fin(true);
-  for (const auto& nv : headers) {
-    expected_ir.SetHeader(nv.first, nv.second);
-  }
-
-  EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
-  // Confirm that mismatches are also detected.
-  headers.push_back({"baz", "bing"});
-  EXPECT_FALSE(cf0.VerifyHasHeaders(headers));
-  EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
-  headers.pop_back();
-  EXPECT_TRUE(cf0.VerifyHasHeaders(headers));
-  EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
-  expected_ir.SetHeader("baz", "bing");
-  EXPECT_FALSE(cf0.VerifyHasFrame(expected_ir));
-  EXPECT_TRUE(cf0.VerifyHasHeaders(headers));
-}
-
-TEST_F(SpdyDeframerVisitorTest, PriorityFrame) {
-  const char kFrameData[] = {
-      0x00,   0x00, 0x05,        // Length: 5
-      0x02,                      //   Type: PRIORITY
-      0x00,                      //  Flags: none
-      0x00,   0x00, 0x00, 0x65,  // Stream: 101
-      '\x80', 0x00, 0x00, 0x01,  // Parent: 1 (Exclusive)
-      0x10,                      // Weight: 17
-  };
-
-  EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
-  ASSERT_EQ(1u, collected_frames_.size());
-  const CollectedFrame& cf0 = collected_frames_[0];
-
-  SpdyPriorityIR expected_ir(/* stream_id = */ 101,
-                             /* parent_stream_id = */ 1, /* weight = */ 17,
-                             /* exclusive = */ true);
-  EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
-  // Confirm that mismatches are also detected.
-  EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(101, 1, 16, true)));
-  EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(101, 50, 17, true)));
-  EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(201, 1, 17, true)));
-  EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(101, 1, 17, false)));
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_RstStreamFrame) {
-  // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, SettingsFrame) {
-  // Settings frame with two entries for the same parameter but with different
-  // values. The last one will be in the decoded SpdySettingsIR, but the vector
-  // of settings will have both, in the same order.
-  const char kFrameData[] = {
-      0x00, 0x00, 0x0c,          // Length
-      0x04,                      // Type (SETTINGS)
-      0x00,                      // Flags
-      0x00, 0x00, 0x00, 0x00,    // Stream id (must be zero)
-      0x00, 0x04,                // Setting id (SETTINGS_INITIAL_WINDOW_SIZE)
-      0x0a, 0x0b, 0x0c, 0x0d,    // Setting value
-      0x00, 0x04,                // Setting id (SETTINGS_INITIAL_WINDOW_SIZE)
-      0x00, 0x00, 0x00, '\xff',  // Setting value
-  };
-
-  EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
-  ASSERT_EQ(1u, collected_frames_.size());
-  const CollectedFrame& cf0 = collected_frames_[0];
-  ASSERT_NE(cf0.frame_ir, nullptr);
-
-  SpdySettingsIR expected_ir;
-  expected_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 255);
-  EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
-  SettingVector expected_settings;
-  expected_settings.push_back({SETTINGS_INITIAL_WINDOW_SIZE, 0x0a0b0c0d});
-  expected_settings.push_back({SETTINGS_INITIAL_WINDOW_SIZE, 255});
-
-  EXPECT_TRUE(cf0.VerifyHasSettings(expected_settings));
-
-  // Confirm that mismatches are also detected.
-  expected_settings.push_back({SETTINGS_INITIAL_WINDOW_SIZE, 65536});
-  EXPECT_FALSE(cf0.VerifyHasSettings(expected_settings));
-
-  expected_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 65536);
-  EXPECT_FALSE(cf0.VerifyHasFrame(expected_ir));
-
-  SpdySettingsIR unexpected_ir;
-  unexpected_ir.set_is_ack(true);
-  EXPECT_FALSE(cf0.VerifyHasFrame(unexpected_ir));
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_PushPromiseFrame) {
-  // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_PingFrame) {
-  // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_GoAwayFrame) {
-  // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_WindowUpdateFrame) {
-  // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_AltSvcFrame) {
-  // TODO(jamessynge): Please implement.
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace spdy
