diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 64f7eea..adbca34 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -24,7 +24,6 @@
 #include "net/third_party/quiche/src/quic/core/quic_config.h"
 #include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
 #include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
-#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h"
 #include "net/third_party/quiche/src/quic/core/quic_types.h"
 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
@@ -294,10 +293,7 @@
           &arena_)),
       visitor_(nullptr),
       debug_visitor_(nullptr),
-      packet_generator_(server_connection_id_,
-                        &framer_,
-                        random_generator_,
-                        this),
+      packet_creator_(server_connection_id_, &framer_, random_generator_, this),
       idle_network_timeout_(QuicTime::Delta::Infinite()),
       handshake_timeout_(QuicTime::Delta::Infinite()),
       time_of_first_packet_sent_after_receiving_(QuicTime::Zero()),
@@ -431,7 +427,7 @@
   sent_packet_manager_.SetFromConfig(config);
   if (config.HasReceivedBytesForConnectionId() &&
       can_truncate_connection_ids_) {
-    packet_generator_.SetServerConnectionIdLength(
+    packet_creator_.SetServerConnectionIdLength(
         config.ReceivedBytesForConnectionId());
   }
   max_undecryptable_packets_ = config.max_undecryptable_packets();
@@ -665,8 +661,8 @@
                   << ", received token "
                   << QuicTextUtils::HexEncode(retry_token);
   server_connection_id_ = new_connection_id;
-  packet_generator_.SetServerConnectionId(server_connection_id_);
-  packet_generator_.SetRetryToken(retry_token);
+  packet_creator_.SetServerConnectionId(server_connection_id_);
+  packet_creator_.SetRetryToken(retry_token);
 
   // Reinstall initial crypters because the connection ID changed.
   InstallInitialCrypters(server_connection_id_);
@@ -759,7 +755,7 @@
              GetServerConnectionIdAsRecipient(header, perspective_)) ||
          PacketCanReplaceConnectionId(header, perspective_));
 
-  if (packet_generator_.HasPendingFrames()) {
+  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 "
@@ -1567,7 +1563,7 @@
                          framer_.supported_versions())
                   << "}, " << (ietf_quic ? "" : "!") << "ietf_quic";
   std::unique_ptr<QuicEncryptedPacket> version_packet(
-      packet_generator_.SerializeVersionNegotiationPacket(
+      packet_creator_.SerializeVersionNegotiationPacket(
           ietf_quic, has_length_prefix, framer_.supported_versions()));
   QUIC_DVLOG(2) << ENDPOINT << "Sending version negotiation packet: {"
                 << ParsedQuicVersionVectorToString(framer_.supported_versions())
@@ -1604,7 +1600,7 @@
     return 0;
   }
   ScopedPacketFlusher flusher(this);
-  return packet_generator_.ConsumeCryptoData(level, write_length, offset);
+  return packet_creator_.ConsumeCryptoData(level, write_length, offset);
 }
 
 QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
@@ -1622,7 +1618,7 @@
   // 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);
-  return packet_generator_.ConsumeData(id, write_length, offset, state);
+  return packet_creator_.ConsumeData(id, write_length, offset, state);
 }
 
 bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
@@ -1640,14 +1636,14 @@
   }
   ScopedPacketFlusher flusher(this);
   const bool consumed =
-      packet_generator_.ConsumeRetransmittableControlFrame(frame);
+      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_generator_.FlushAllQueuedFrames();
+    packet_creator_.FlushCurrentPacket();
     if (debug_visitor_ != nullptr) {
       debug_visitor_->OnPingSent();
     }
@@ -1666,9 +1662,9 @@
     return;
   }
   // Flush stream frames of reset stream.
-  if (packet_generator_.HasPendingStreamFramesOfStream(id)) {
+  if (packet_creator_.HasPendingStreamFramesOfStream(id)) {
     ScopedPacketFlusher flusher(this);
-    packet_generator_.FlushAllQueuedFrames();
+    packet_creator_.FlushCurrentPacket();
   }
 
   // Remove all queued packets which only contain data for the reset stream.
@@ -1711,7 +1707,7 @@
   stats_.srtt_us = srtt.ToMicroseconds();
 
   stats_.estimated_bandwidth = sent_packet_manager_.BandwidthEstimate();
-  stats_.max_packet_size = packet_generator_.GetCurrentMaxPacketLength();
+  stats_.max_packet_size = packet_creator_.max_packet_length();
   stats_.max_received_packet_size = largest_received_packet_size_;
   return stats_;
 }
@@ -1950,7 +1946,7 @@
                     << server_connection_id_ << " with "
                     << header.source_connection_id;
     server_connection_id_ = header.source_connection_id;
-    packet_generator_.SetServerConnectionId(server_connection_id_);
+    packet_creator_.SetServerConnectionId(server_connection_id_);
   }
 
   if (!ValidateReceivedPacketNumber(header.packet_number)) {
@@ -1965,7 +1961,7 @@
         // it should stop sending version since the version negotiation is done.
         // IETF QUIC stops sending version once encryption level switches to
         // forward secure.
-        packet_generator_.StopSendingVersion();
+        packet_creator_.StopSendingVersion();
       }
       version_negotiated_ = true;
       visitor_->OnSuccessfulVersionNegotiation(version());
@@ -1981,7 +1977,7 @@
 
   if (perspective_ == Perspective::IS_SERVER &&
       encryption_level_ == ENCRYPTION_INITIAL &&
-      last_size_ > packet_generator_.GetCurrentMaxPacketLength()) {
+      last_size_ > packet_creator_.max_packet_length()) {
     SetMaxPacketLength(last_size_);
   }
   return true;
@@ -2243,7 +2239,7 @@
                                     packet->encrypted_length > long_term_mtu_;
   DCHECK_LE(encrypted_length, kMaxOutgoingPacketSize);
   if (!looks_like_mtu_probe) {
-    DCHECK_LE(encrypted_length, packet_generator_.GetCurrentMaxPacketLength());
+    DCHECK_LE(encrypted_length, packet_creator_.max_packet_length());
   }
   QUIC_DVLOG(1) << ENDPOINT << "Sending packet " << packet_number << " : "
                 << (IsRetransmittable(*packet) == HAS_RETRANSMITTABLE_DATA
@@ -2279,7 +2275,7 @@
       if (!coalesced_packet_.MaybeCoalescePacket(
               *packet, self_address(), peer_address(),
               helper_->GetStreamSendBufferAllocator(),
-              packet_generator_.GetCurrentMaxPacketLength())) {
+              packet_creator_.max_packet_length())) {
         // Failed to coalesce packet, flush current coalesced packet.
         if (!FlushCoalescedPacket()) {
           // Failed to flush coalesced packet, write error has been handled.
@@ -2288,7 +2284,7 @@
         if (!coalesced_packet_.MaybeCoalescePacket(
                 *packet, self_address(), peer_address(),
                 helper_->GetStreamSendBufferAllocator(),
-                packet_generator_.GetCurrentMaxPacketLength())) {
+                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";
@@ -2300,7 +2296,7 @@
         QUIC_DVLOG(1) << ENDPOINT << "Trying to set soft max packet length to "
                       << coalesced_packet_.max_packet_length() -
                              coalesced_packet_.length();
-        packet_generator_.SetSoftMaxPacketLength(
+        packet_creator_.SetSoftMaxPacketLength(
             coalesced_packet_.max_packet_length() - coalesced_packet_.length());
       }
       break;
@@ -2422,7 +2418,7 @@
 
   // The packet number length must be updated after OnPacketSent, because it
   // may change the packet number length in packet.
-  packet_generator_.UpdatePacketNumberLength(
+  packet_creator_.UpdatePacketNumberLength(
       sent_packet_manager_.GetLeastUnacked(),
       sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
 
@@ -2644,7 +2640,7 @@
     PopulateStopWaitingFrame(&stop_waiting);
     frames.push_back(QuicFrame(stop_waiting));
   }
-  if (!packet_generator_.FlushAckFrame(frames)) {
+  if (!packet_creator_.FlushAckFrame(frames)) {
     return;
   }
   ResetAckStates();
@@ -2653,7 +2649,7 @@
     return;
   }
   consecutive_num_packets_with_no_retransmittable_frames_ = 0;
-  if (packet_generator_.HasRetransmittableFrames() ||
+  if (packet_creator_.HasPendingRetransmittableFrames() ||
       visitor_->WillingAndAbleToWrite()) {
     // There are pending retransmittable frames.
     return;
@@ -2672,7 +2668,7 @@
          (sent_packet_manager_.handshake_mode_disabled() &&
           !sent_packet_manager_.handshake_confirmed()));
   const QuicPacketNumber previous_created_packet_number =
-      packet_generator_.packet_number();
+      packet_creator_.packet_number();
   if (close_connection_after_five_rtos_ &&
       sent_packet_manager_.GetConsecutiveRtoCount() >= 4) {
     // Close on the 5th consecutive RTO, so after 4 previous RTOs have occurred.
@@ -2696,7 +2692,7 @@
       sent_packet_manager_.pending_timer_transmission_count() == 1) {
     // Skip a packet number when a single PTO packet is sent to elicit an
     // immediate ACK.
-    packet_generator_.SkipNPacketNumbers(
+    packet_creator_.SkipNPacketNumbers(
         1, sent_packet_manager_.GetLeastUnacked(),
         sent_packet_manager_.EstimateMaxPacketsInFlight(max_packet_length()));
   }
@@ -2717,7 +2713,7 @@
     WriteIfNotBlocked();
   }
 
-  if (packet_generator_.packet_number() == previous_created_packet_number &&
+  if (packet_creator_.packet_number() == previous_created_packet_number &&
       (retransmission_mode == QuicSentPacketManager::TLP_MODE ||
        retransmission_mode == QuicSentPacketManager::RTO_MODE ||
        retransmission_mode == QuicSentPacketManager::PTO_MODE) &&
@@ -2743,12 +2739,12 @@
     // When timer fires in TLP or RTO 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(packet_generator_.packet_number() ==
+    QUIC_BUG_IF(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_generator_.packet_number()
+        << ", packet_number: " << packet_creator_.packet_number()
         << ", session has data to write: " << visitor_->WillingAndAbleToWrite()
         << ", writer is blocked: " << writer_->IsWriteBlocked()
         << ", pending_timer_transmission_count: "
@@ -2766,26 +2762,26 @@
 
 void QuicConnection::SetEncrypter(EncryptionLevel level,
                                   std::unique_ptr<QuicEncrypter> encrypter) {
-  packet_generator_.SetEncrypter(level, std::move(encrypter));
+  packet_creator_.SetEncrypter(level, std::move(encrypter));
 }
 
 void QuicConnection::SetDiversificationNonce(
     const DiversificationNonce& nonce) {
   DCHECK_EQ(Perspective::IS_SERVER, perspective_);
-  packet_generator_.SetDiversificationNonce(nonce);
+  packet_creator_.SetDiversificationNonce(nonce);
 }
 
 void QuicConnection::SetDefaultEncryptionLevel(EncryptionLevel level) {
   QUIC_DVLOG(1) << ENDPOINT << "Setting default encryption level from "
                 << EncryptionLevelToString(encryption_level_) << " to "
                 << EncryptionLevelToString(level);
-  if (level != encryption_level_ && packet_generator_.HasPendingFrames()) {
+  if (level != encryption_level_ && packet_creator_.HasPendingFrames()) {
     // Flush all queued frames when encryption level changes.
     ScopedPacketFlusher flusher(this);
-    packet_generator_.FlushAllQueuedFrames();
+    packet_creator_.FlushCurrentPacket();
   }
   encryption_level_ = level;
-  packet_generator_.set_encryption_level(level);
+  packet_creator_.set_encryption_level(level);
 }
 
 void QuicConnection::SetDecrypter(EncryptionLevel level,
@@ -2856,7 +2852,7 @@
   while (connected_ && !undecryptable_packets_.empty()) {
     // Making sure there is no pending frames when processing next undecrypted
     // packet because the queued ack frame may change.
-    packet_generator_.FlushAllQueuedFrames();
+    packet_creator_.FlushCurrentPacket();
     if (!connected_) {
       return;
     }
@@ -2899,7 +2895,7 @@
   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_generator_.FlushAllQueuedFrames();
+    packet_creator_.FlushCurrentPacket();
     if (!connected_) {
       return;
     }
@@ -2966,8 +2962,8 @@
 
     frame = new QuicConnectionCloseFrame(transport_version(), error, details,
                                          framer_.current_received_frame_type());
-    packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
-    packet_generator_.FlushAllQueuedFrames();
+    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
+    packet_creator_.FlushCurrentPacket();
     if (version().CanSendCoalescedPackets()) {
       FlushCoalescedPacket();
     }
@@ -3002,8 +2998,8 @@
     auto* frame =
         new QuicConnectionCloseFrame(transport_version(), error, details,
                                      framer_.current_received_frame_type());
-    packet_generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
-    packet_generator_.FlushAllQueuedFrames();
+    packet_creator_.ConsumeRetransmittableControlFrame(QuicFrame(frame));
+    packet_creator_.FlushCurrentPacket();
     if (!version().CanSendCoalescedPackets()) {
       ClearQueuedPackets();
     }
@@ -3059,17 +3055,17 @@
 }
 
 QuicByteCount QuicConnection::max_packet_length() const {
-  return packet_generator_.GetCurrentMaxPacketLength();
+  return packet_creator_.max_packet_length();
 }
 
 void QuicConnection::SetMaxPacketLength(QuicByteCount length) {
   long_term_mtu_ = length;
-  packet_generator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length));
+  packet_creator_.SetMaxPacketLength(GetLimitedMaxPacketSize(length));
 }
 
 bool QuicConnection::HasQueuedData() const {
   return pending_version_negotiation_packet_ || !queued_packets_.empty() ||
-         packet_generator_.HasPendingFrames() || !buffered_packets_.empty();
+         packet_creator_.HasPendingFrames() || !buffered_packets_.empty();
 }
 
 bool QuicConnection::CanWriteStreamData() {
@@ -3226,7 +3222,7 @@
 }
 
 void QuicConnection::SetRetransmissionAlarm() {
-  if (packet_generator_.PacketFlusherAttached()) {
+  if (packet_creator_.PacketFlusherAttached()) {
     pending_retransmission_alarm_ = true;
     return;
   }
@@ -3296,9 +3292,9 @@
     return;
   }
 
-  if (!connection_->packet_generator_.PacketFlusherAttached()) {
+  if (!connection_->packet_creator_.PacketFlusherAttached()) {
     flush_and_set_pending_retransmission_alarm_on_delete_ = true;
-    connection->packet_generator_.AttachPacketFlusher();
+    connection->packet_creator_.AttachPacketFlusher();
   }
 }
 
@@ -3337,7 +3333,7 @@
         connection_->SendAck();
       }
     }
-    connection_->packet_generator_.Flush();
+    connection_->packet_creator_.Flush();
     if (connection_->version().CanSendCoalescedPackets()) {
       connection_->FlushCoalescedPacket();
     }
@@ -3371,7 +3367,7 @@
     }
   }
   DCHECK_EQ(flush_and_set_pending_retransmission_alarm_on_delete_,
-            !connection_->packet_generator_.PacketFlusherAttached());
+            !connection_->packet_creator_.PacketFlusherAttached());
 }
 
 QuicConnection::BufferedPacket::BufferedPacket(
@@ -3454,7 +3450,7 @@
   DCHECK_EQ(target_mtu, GetLimitedMaxPacketSize(target_mtu));
 
   // Send the probe.
-  packet_generator_.GenerateMtuDiscoveryPacket(target_mtu);
+  packet_creator_.GenerateMtuDiscoveryPacket(target_mtu);
 }
 
 // TODO(zhongyi): change this method to generate a connectivity probing packet
@@ -3509,7 +3505,7 @@
   if (!VersionHasIetfQuicFrames(transport_version())) {
     // Non-IETF QUIC, generate a padded ping regardless of whether this is a
     // request or a response.
-    probing_packet = packet_generator_.SerializeConnectivityProbingPacket();
+    probing_packet = packet_creator_.SerializeConnectivityProbingPacket();
   } else {
     if (is_response) {
       // Respond using IETF QUIC PATH_RESPONSE frame
@@ -3517,14 +3513,14 @@
         // Pad the response if the request was a google connectivity probe
         // (padded).
         probing_packet =
-            packet_generator_.SerializePathResponseConnectivityProbingPacket(
+            packet_creator_.SerializePathResponseConnectivityProbingPacket(
                 received_path_challenge_payloads_, /* is_padded = */ true);
         received_path_challenge_payloads_.clear();
       } else {
         // Do not pad the response if the path challenge was not a google
         // connectivity probe.
         probing_packet =
-            packet_generator_.SerializePathResponseConnectivityProbingPacket(
+            packet_creator_.SerializePathResponseConnectivityProbingPacket(
                 received_path_challenge_payloads_,
                 /* is_padded = */ false);
         received_path_challenge_payloads_.clear();
@@ -3534,7 +3530,7 @@
       transmitted_connectivity_probe_payload_ =
           std::make_unique<QuicPathFrameBuffer>();
       probing_packet =
-          packet_generator_.SerializePathChallengeConnectivityProbingPacket(
+          packet_creator_.SerializePathChallengeConnectivityProbingPacket(
               transmitted_connectivity_probe_payload_.get());
       if (!probing_packet) {
         transmitted_connectivity_probe_payload_ = nullptr;
@@ -3847,7 +3843,7 @@
 }
 
 void QuicConnection::SetTransmissionType(TransmissionType type) {
-  packet_generator_.SetTransmissionType(type);
+  packet_creator_.SetTransmissionType(type);
 }
 
 void QuicConnection::UpdateReleaseTimeIntoFuture() {
@@ -3882,15 +3878,15 @@
     return MESSAGE_STATUS_BLOCKED;
   }
   ScopedPacketFlusher flusher(this);
-  return packet_generator_.AddMessageFrame(message_id, message);
+  return packet_creator_.AddMessageFrame(message_id, message);
 }
 
 QuicPacketLength QuicConnection::GetCurrentLargestMessagePayload() const {
-  return packet_generator_.GetCurrentLargestMessagePayload();
+  return packet_creator_.GetCurrentLargestMessagePayload();
 }
 
 QuicPacketLength QuicConnection::GetGuaranteedLargestMessagePayload() const {
-  return packet_generator_.GetGuaranteedLargestMessagePayload();
+  return packet_creator_.GetGuaranteedLargestMessagePayload();
 }
 
 uint32_t QuicConnection::cipher_id() const {
@@ -3953,7 +3949,7 @@
     QuicFrames frames;
     frames.push_back(uber_received_packet_manager_.GetUpdatedAckFrame(
         static_cast<PacketNumberSpace>(i), clock_->ApproximateNow()));
-    const bool flushed = packet_generator_.FlushAckFrame(frames);
+    const bool flushed = packet_creator_.FlushAckFrame(frames);
     if (!flushed) {
       // Connection is write blocked.
       QUIC_BUG_IF(!writer_->IsWriteBlocked())
@@ -3979,7 +3975,7 @@
     return;
   }
   consecutive_num_packets_with_no_retransmittable_frames_ = 0;
-  if (packet_generator_.HasRetransmittableFrames() ||
+  if (packet_creator_.HasPendingRetransmittableFrames() ||
       visitor_->WillingAndAbleToWrite()) {
     // There are pending retransmittable frames.
     return;
@@ -3999,7 +3995,7 @@
   }
   QUIC_DVLOG(1) << ENDPOINT << "Sending coalesced packet";
   char buffer[kMaxOutgoingPacketSize];
-  const size_t length = packet_generator_.SerializeCoalescedPacket(
+  const size_t length = packet_creator_.SerializeCoalescedPacket(
       coalesced_packet_, buffer, coalesced_packet_.max_packet_length());
   if (length == 0) {
     return false;
@@ -4176,7 +4172,7 @@
                   << client_connection_id_
                   << " for connection with server connection ID "
                   << server_connection_id_;
-  packet_generator_.SetClientConnectionId(client_connection_id_);
+  packet_creator_.SetClientConnectionId(client_connection_id_);
   framer_.SetExpectedClientConnectionIdLength(client_connection_id_.length());
 }
 
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 7bbd931..d858e3a 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -37,7 +37,6 @@
 #include "net/third_party/quiche/src/quic/core/quic_mtu_discovery.h"
 #include "net/third_party/quiche/src/quic/core/quic_one_block_arena.h"
 #include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
-#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h"
 #include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
 #include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h"
@@ -513,12 +512,10 @@
   void OnAuthenticatedIetfStatelessResetPacket(
       const QuicIetfStatelessResetPacket& packet) override;
 
-  // QuicPacketGenerator::DelegateInterface
+  // QuicPacketCreator::DelegateInterface
   bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
                             IsHandshake handshake) override;
   const QuicFrames MaybeBundleAckOpportunistically() override;
-
-  // QuicPacketCreator::DelegateInterface
   char* GetPacketBuffer() override;
   void OnSerializedPacket(SerializedPacket* packet) override;
   void OnUnrecoverableError(QuicErrorCode error,
@@ -566,7 +563,7 @@
   }
   // Used in Chromium, but not internally.
   void set_creator_debug_delegate(QuicPacketCreator::DebugDelegate* visitor) {
-    packet_generator_.set_debug_delegate(visitor);
+    packet_creator_.set_debug_delegate(visitor);
   }
   const QuicSocketAddress& self_address() const { return self_address_; }
   const QuicSocketAddress& peer_address() const { return direct_peer_address_; }
@@ -784,9 +781,7 @@
 
   const QuicFramer& framer() const { return framer_; }
 
-  const QuicPacketGenerator& packet_generator() const {
-    return packet_generator_;
-  }
+  const QuicPacketCreator& packet_creator() const { return packet_creator_; }
 
   EncryptionLevel encryption_level() const { return encryption_level_; }
   EncryptionLevel last_decrypted_level() const {
@@ -811,11 +806,11 @@
   // 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_generator_.set_fully_pad_crypto_handshake_packets(new_value);
+    packet_creator_.set_fully_pad_crypto_handshake_packets(new_value);
   }
 
   bool fully_pad_during_crypto_handshake() const {
-    return packet_generator_.fully_pad_crypto_handshake_packets();
+    return packet_creator_.fully_pad_crypto_handshake_packets();
   }
 
   size_t min_received_before_ack_decimation() const;
@@ -1344,7 +1339,7 @@
   QuicConnectionVisitorInterface* visitor_;
   QuicConnectionDebugVisitor* debug_visitor_;
 
-  QuicPacketGenerator packet_generator_;
+  QuicPacketCreator packet_creator_;
 
   // Network idle time before this connection is closed.
   QuicTime::Delta idle_network_timeout_;
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 5a2e0ef..5194a9c 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -36,7 +36,6 @@
 #include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
 #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
@@ -969,7 +968,6 @@
                     Perspective::IS_CLIENT,
                     version()),
         creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
-        generator_(QuicConnectionPeer::GetPacketGenerator(&connection_)),
         manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
         frame1_(0, false, 0, QuicStringPiece(data1)),
         frame2_(0, false, 3, QuicStringPiece(data2)),
@@ -1625,7 +1623,6 @@
   std::unique_ptr<TestPacketWriter> writer_;
   TestConnection connection_;
   QuicPacketCreator* creator_;
-  QuicPacketGenerator* generator_;
   QuicSentPacketManager* manager_;
   StrictMock<MockQuicConnectionVisitor> visitor_;
 
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index ac467a2..b64ed3f 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -125,14 +125,9 @@
       flusher_attached_(false),
       fully_pad_crypto_handshake_packets_(true),
       latched_hard_max_packet_length_(0),
-      combine_generator_and_creator_(
-          GetQuicReloadableFlag(quic_combine_generator_and_creator)),
       populate_nonretransmittable_frames_(
           GetQuicReloadableFlag(quic_populate_nonretransmittable_frames)) {
   SetMaxPacketLength(kDefaultMaxPacketSize);
-  if (combine_generator_and_creator_) {
-    QUIC_RELOADABLE_FLAG_COUNT(quic_combine_generator_and_creator);
-  }
   if (populate_nonretransmittable_frames_) {
     QUIC_RELOADABLE_FLAG_COUNT(quic_populate_nonretransmittable_frames);
   }
@@ -1098,7 +1093,6 @@
 
 bool QuicPacketCreator::ConsumeRetransmittableControlFrame(
     const QuicFrame& frame) {
-  DCHECK(combine_generator_and_creator_);
   QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
       << "Adding a control frame with no control frame id: " << frame;
   DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
@@ -1126,7 +1120,6 @@
                                                 size_t write_length,
                                                 QuicStreamOffset offset,
                                                 StreamSendingState state) {
-  DCHECK(combine_generator_and_creator_);
   QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
                                      "generator tries to write stream data.";
   bool has_handshake = QuicUtils::IsCryptoStreamId(transport_version(), id);
@@ -1218,7 +1211,6 @@
     QuicStreamOffset offset,
     bool fin,
     size_t total_bytes_consumed) {
-  DCHECK(combine_generator_and_creator_);
   DCHECK(!QuicUtils::IsCryptoStreamId(transport_version(), id));
 
   while (total_bytes_consumed < write_length &&
@@ -1239,7 +1231,6 @@
 size_t QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
                                             size_t write_length,
                                             QuicStreamOffset offset) {
-  DCHECK(combine_generator_and_creator_);
   QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
                                      "generator tries to write crypto data.";
   MaybeBundleAckOpportunistically();
@@ -1277,7 +1268,6 @@
 }
 
 void QuicPacketCreator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
-  DCHECK(combine_generator_and_creator_);
   // MTU discovery frames must be sent by themselves.
   if (!CanSetMaxPacketLength()) {
     QUIC_BUG << "MTU discovery packets should only be sent when no other "
@@ -1305,7 +1295,6 @@
 }
 
 void QuicPacketCreator::MaybeBundleAckOpportunistically() {
-  DCHECK(combine_generator_and_creator_);
   if (has_ack()) {
     // Ack already queued, nothing to do.
     return;
@@ -1321,7 +1310,6 @@
 }
 
 bool QuicPacketCreator::FlushAckFrame(const QuicFrames& frames) {
-  DCHECK(combine_generator_and_creator_);
   QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
                                      "generator tries to send ACK frame.";
   for (const auto& frame : frames) {
@@ -1346,12 +1334,10 @@
 }
 
 void QuicPacketCreator::AddRandomPadding() {
-  DCHECK(combine_generator_and_creator_);
   AddPendingPadding(random_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
 }
 
 void QuicPacketCreator::AttachPacketFlusher() {
-  DCHECK(combine_generator_and_creator_);
   flusher_attached_ = true;
   if (!write_start_packet_number_.IsInitialized()) {
     write_start_packet_number_ = NextSendingPacketNumber();
@@ -1359,7 +1345,6 @@
 }
 
 void QuicPacketCreator::Flush() {
-  DCHECK(combine_generator_and_creator_);
   FlushCurrentPacket();
   SendRemainingPendingPadding();
   flusher_attached_ = false;
@@ -1377,7 +1362,6 @@
 }
 
 void QuicPacketCreator::SendRemainingPendingPadding() {
-  DCHECK(combine_generator_and_creator_);
   while (
       pending_padding_bytes() > 0 && !HasPendingFrames() &&
       delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
@@ -1386,7 +1370,6 @@
 }
 
 void QuicPacketCreator::SetServerConnectionIdLength(uint32_t length) {
-  DCHECK(combine_generator_and_creator_);
   if (length == 0) {
     SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
   } else {
@@ -1395,13 +1378,11 @@
 }
 
 void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
-  DCHECK(combine_generator_and_creator_);
   next_transmission_type_ = type;
 }
 
 MessageStatus QuicPacketCreator::AddMessageFrame(QuicMessageId message_id,
                                                  QuicMemSliceSpan message) {
-  DCHECK(combine_generator_and_creator_);
   QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
                                      "generator tries to add message frame.";
   MaybeBundleAckOpportunistically();
@@ -1809,7 +1790,6 @@
 }
 
 bool QuicPacketCreator::PacketFlusherAttached() const {
-  DCHECK(combine_generator_and_creator_);
   return flusher_attached_;
 }
 
diff --git a/quic/core/quic_packet_creator.h b/quic/core/quic_packet_creator.h
index b8240c1..7460502 100644
--- a/quic/core/quic_packet_creator.h
+++ b/quic/core/quic_packet_creator.h
@@ -2,8 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Accumulates frames for the next packet until more frames no longer fit or
-// it's time to create a packet from them.
+// 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_
@@ -377,19 +384,13 @@
   bool PacketFlusherAttached() const;
 
   void set_fully_pad_crypto_handshake_packets(bool new_value) {
-    DCHECK(combine_generator_and_creator_);
     fully_pad_crypto_handshake_packets_ = new_value;
   }
 
   bool fully_pad_crypto_handshake_packets() const {
-    DCHECK(combine_generator_and_creator_);
     return fully_pad_crypto_handshake_packets_;
   }
 
-  bool combine_generator_and_creator() const {
-    return combine_generator_and_creator_;
-  }
-
   // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also
   // fills the packet with padding.
   size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header,
@@ -592,9 +593,6 @@
   // set to a soft value.
   QuicByteCount latched_hard_max_packet_length_;
 
-  // Latched value of quic_combine_generator_and_creator.
-  const bool combine_generator_and_creator_;
-
   // Latched value of quic_populate_nonretransmittable_frames.
   const bool populate_nonretransmittable_frames_;
 };
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index 4efcbfe..25161e1 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -30,6 +30,7 @@
 #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
 #include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
+#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
 
 using testing::_;
 using testing::DoAll;
@@ -2239,6 +2240,1495 @@
   EXPECT_TRUE(creator_.HasPendingFrames());
 }
 
+class MockDelegate : public QuicPacketCreator::DelegateInterface {
+ public:
+  MockDelegate() {}
+  MockDelegate(const MockDelegate&) = delete;
+  MockDelegate& operator=(const MockDelegate&) = delete;
+  ~MockDelegate() override {}
+
+  MOCK_METHOD2(ShouldGeneratePacket,
+               bool(HasRetransmittableData retransmittable,
+                    IsHandshake handshake));
+  MOCK_METHOD0(MaybeBundleAckOpportunistically, const QuicFrames());
+  MOCK_METHOD0(GetPacketBuffer, char*());
+  MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
+  MOCK_METHOD2(OnUnrecoverableError, void(QuicErrorCode, const std::string&));
+
+  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,
+                                       const struct iovec* iov,
+                                       int iov_count,
+                                       size_t total_length,
+                                       QuicStreamOffset offset,
+                                       bool fin) {
+    // Save data before data is consumed.
+    if (total_length > 0) {
+      producer_->SaveStreamData(id, iov, iov_count, 0, total_length);
+    }
+    return QuicPacketCreator::ConsumeDataFastPath(id, total_length, offset, fin,
+                                                  0);
+  }
+
+  QuicConsumedData ConsumeData(QuicStreamId id,
+                               const struct iovec* iov,
+                               int iov_count,
+                               size_t total_length,
+                               QuicStreamOffset offset,
+                               StreamSendingState state) {
+    // Save data before data is consumed.
+    if (total_length > 0) {
+      producer_->SaveStreamData(id, iov, iov_count, 0, total_length);
+    }
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::ConsumeData(id, total_length, offset, state);
+  }
+
+  MessageStatus AddMessageFrame(QuicMessageId message_id,
+                                QuicMemSliceSpan message) {
+    if (!has_ack() && delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
+                                                      NOT_HANDSHAKE)) {
+      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
+    }
+    return QuicPacketCreator::AddMessageFrame(message_id, message);
+  }
+
+  size_t ConsumeCryptoData(EncryptionLevel level,
+                           QuicStringPiece 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(nullptr));
+    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 {
+    for (SerializedPacket& packet : packets_) {
+      delete[] packet.encrypted_buffer;
+      ClearSerializedPacket(&packet);
+    }
+  }
+
+  void SavePacket(SerializedPacket* packet) {
+    packet->encrypted_buffer = CopyBuffer(*packet);
+    packets_.push_back(*packet);
+    packet->encrypted_buffer = nullptr;
+    packet->retransmittable_frames.clear();
+  }
+
+ 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);
+    }
+  }
+
+  void CreateData(size_t len) {
+    data_array_.reset(new char[len]);
+    memset(data_array_.get(), '?', len);
+    iov_.iov_base = data_array_.get();
+    iov_.iov_len = len;
+  }
+
+  QuicFramer framer_;
+  MockRandom random_creator_;
+  StrictMock<MockDelegate> delegate_;
+  MultiplePacketsTestPacketCreator creator_;
+  SimpleQuicFramer simple_framer_;
+  std::vector<SerializedPacket> packets_;
+  QuicAckFrame ack_frame_;
+  struct iovec iov_;
+  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, 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, ConsumeData_NotWritable) {
+  delegate_.SetCanNotWrite();
+
+  MakeIOVector("foo", &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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();
+
+  MakeIOVector("foo", &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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));
+  MakeIOVector("foo", &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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));
+  std::string data = "foo bar";
+  MakeIOVector(data, &iov_);
+  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()),
+                &iov_, 1u, iov_.iov_len, 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));
+  std::string data = "foo";
+  MakeIOVector(data, &iov_);
+  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()),
+                &iov_, 1u, iov_.iov_len, 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),
+                      nullptr, 0, 0, 0, NO_FIN),
+                  "Attempt to consume empty data without FIN.");
+}
+
+TEST_F(QuicPacketCreatorMultiplePacketsTest,
+       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
+  delegate_.SetCanWriteAnything();
+
+  MakeIOVector("foo", &iov_);
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       &iov_, 1u, iov_.iov_len, 0, FIN);
+  MakeIOVector("quux", &iov_);
+  QuicConsumedData consumed =
+      creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 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();
+
+  MakeIOVector("foo", &iov_);
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       &iov_, 1u, iov_.iov_len, 0, NO_FIN);
+  MakeIOVector("quux", &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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 =
+      GetQuicReloadableFlag(quic_coalesce_stream_frames) ? 1 : 2;
+  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.
+  MakeIOVector("foo", &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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.
+  MakeIOVector("bar", &iov_);
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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);
+
+  // Create a 10000 byte IOVector.
+  CreateData(10000);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeDataFastPath(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 0, true);
+  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();
+
+  // Create a 10000 byte IOVector.
+  CreateData(10000);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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);
+
+  // Create a 10000 byte IOVector.
+  CreateData(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),
+      &iov_, 1u, iov_.iov_len, 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) {
+  if (VersionHasIetfInvariantHeader(framer_.transport_version())) {
+    return;
+  }
+  delegate_.SetCanNotWrite();
+  delegate_.SetCanWriteAnything();
+
+  // Create a 10000 byte IOVector.
+  CreateData(10000);
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillRepeatedly(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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
+  MakeIOVector("quux", &iov_);
+  creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 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;
+  CreateData(data_len);
+  QuicConsumedData consumed =
+      creator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 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 = 1324;
+  CreateData(data_len);
+  QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId(
+      framer_.transport_version(), Perspective::IS_CLIENT);
+  QuicConsumedData consumed =
+      creator_.ConsumeData(stream1_id, &iov_, 1u, iov_.iov_len, 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, &iov_, 1u, iov_.iov_len, 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 (VersionHasIetfInvariantHeader(framer_.transport_version())) {
+      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));
+  CreateData(data_len);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len,
+      /*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.
+  CreateData(data_len);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len,
+      /*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.
+  CreateData(data_len);
+  creator_.AttachPacketFlusher();
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len, 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.
+  CreateData(first_write_len);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len,
+      /*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.
+  CreateData(second_write_len);
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len,
+      /*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();
+
+  OwningSerializedPacketPointer 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.
+  CreateData(data_len);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len,
+      /*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.
+  CreateData(data_len);
+  creator_.AttachPacketFlusher();
+  consumed = creator_.ConsumeData(
+      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
+                                               Perspective::IS_CLIENT),
+      &iov_, 1u, iov_.iov_len,
+      /*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] = {};
+  QuicStringPiece error_details(buf, 2000);
+  const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR;
+
+  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
+      framer_.transport_version(), kQuicErrorCode, 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));
+  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId, &iov_, 1u, iov_.iov_len, 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));
+  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId, &iov_, 1u, iov_.iov_len, 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));
+  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
+  QuicConsumedData consumed = creator_.ConsumeData(
+      kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
+  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
+  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
+  consumed = creator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 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;
+  }
+  quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
+  delegate_.SetCanWriteAnything();
+  EXPECT_CALL(delegate_, OnSerializedPacket(_))
+      .WillOnce(
+          Invoke(this, &QuicPacketCreatorMultiplePacketsTest::SavePacket));
+
+  MakeIOVector("foo", &iov_);
+  creator_.ConsumeData(QuicUtils::GetFirstBidirectionalStreamId(
+                           framer_.transport_version(), Perspective::IS_CLIENT),
+                       &iov_, 1u, iov_.iov_len, 0, FIN);
+  EXPECT_EQ(
+      MESSAGE_STATUS_SUCCESS,
+      creator_.AddMessageFrame(1, MakeSpan(&allocator_, "message", &storage)));
+  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,
+          MakeSpan(&allocator_,
+                   std::string(creator_.GetCurrentLargestMessagePayload(), 'a'),
+                   &storage)));
+  EXPECT_TRUE(creator_.HasPendingRetransmittableFrames());
+
+  // Failed to send messages which cannot fit into one packet.
+  EXPECT_EQ(
+      MESSAGE_STATUS_TOO_LARGE,
+      creator_.AddMessageFrame(
+          3, MakeSpan(&allocator_,
+                      std::string(
+                          creator_.GetCurrentLargestMessagePayload() + 10, 'a'),
+                      &storage)));
+}
+
+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());
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/quic/core/quic_packet_generator.cc b/quic/core/quic_packet_generator.cc
deleted file mode 100644
index f4a5773..0000000
--- a/quic/core/quic_packet_generator.cc
+++ /dev/null
@@ -1,553 +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 "net/third_party/quiche/src/quic/core/quic_packet_generator.h"
-
-#include <cstdint>
-
-#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
-#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
-#include "net/third_party/quiche/src/quic/core/quic_types.h"
-#include "net/third_party/quiche/src/quic/core/quic_utils.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
-
-namespace quic {
-
-QuicPacketGenerator::QuicPacketGenerator(
-    QuicConnectionId server_connection_id,
-    QuicFramer* framer,
-    QuicRandom* random_generator,
-    QuicPacketCreator::DelegateInterface* delegate)
-    : delegate_(delegate),
-      packet_creator_(server_connection_id, framer, random_generator, delegate),
-      next_transmission_type_(NOT_RETRANSMISSION),
-      flusher_attached_(false),
-      random_generator_(random_generator),
-      fully_pad_crypto_handshake_packets_(true) {}
-
-QuicPacketGenerator::~QuicPacketGenerator() {}
-
-bool QuicPacketGenerator::ConsumeRetransmittableControlFrame(
-    const QuicFrame& frame) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.ConsumeRetransmittableControlFrame(frame);
-  }
-  QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
-      << "Adding a control frame with no control frame id: " << frame;
-  DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
-  MaybeBundleAckOpportunistically();
-  if (packet_creator_.HasPendingFrames()) {
-    if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
-      // There is pending frames and current frame fits.
-      return true;
-    }
-  }
-  DCHECK(!packet_creator_.HasPendingFrames());
-  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 =
-      packet_creator_.AddSavedFrame(frame, next_transmission_type_);
-  DCHECK(success);
-  return success;
-}
-
-size_t QuicPacketGenerator::ConsumeCryptoData(EncryptionLevel level,
-                                              size_t write_length,
-                                              QuicStreamOffset offset) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.ConsumeCryptoData(level, write_length, offset);
-  }
-  QUIC_BUG_IF(!flusher_attached_) << "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 (packet_creator_.HasPendingRetransmittableFrames()) {
-    packet_creator_.FlushCurrentPacket();
-  }
-
-  size_t total_bytes_consumed = 0;
-
-  while (total_bytes_consumed < write_length) {
-    QuicFrame frame;
-    if (!packet_creator_.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 << "Failed to ConsumeCryptoData at level " << level;
-      return 0;
-    }
-    total_bytes_consumed += frame.crypto_frame->data_length;
-
-    // TODO(ianswett): Move to having the creator flush itself when it's full.
-    packet_creator_.FlushCurrentPacket();
-  }
-
-  // Don't allow the handshake to be bundled with other retransmittable frames.
-  packet_creator_.FlushCurrentPacket();
-
-  return total_bytes_consumed;
-}
-
-QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
-                                                  size_t write_length,
-                                                  QuicStreamOffset offset,
-                                                  StreamSendingState state) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.ConsumeData(id, write_length, offset, state);
-  }
-  QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
-                                     "generator tries to write stream data.";
-  bool has_handshake =
-      QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id);
-  MaybeBundleAckOpportunistically();
-  bool fin = state != NO_FIN;
-  QUIC_BUG_IF(has_handshake && fin)
-      << "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 && packet_creator_.HasPendingRetransmittableFrames()) {
-    packet_creator_.FlushCurrentPacket();
-  }
-
-  size_t total_bytes_consumed = 0;
-  bool fin_consumed = false;
-
-  if (!packet_creator_.HasRoomForStreamFrame(id, offset, write_length)) {
-    packet_creator_.FlushCurrentPacket();
-  }
-
-  if (!fin && (write_length == 0)) {
-    QUIC_BUG << "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;
-
-  while (!run_fast_path && delegate_->ShouldGeneratePacket(
-                               HAS_RETRANSMITTABLE_DATA,
-                               has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
-    QuicFrame frame;
-    bool needs_full_padding =
-        has_handshake && fully_pad_crypto_handshake_packets_;
-
-    if (!packet_creator_.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 << "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();
-    }
-    DCHECK(total_bytes_consumed == write_length ||
-           (bytes_consumed > 0 && packet_creator_.HasPendingFrames()));
-
-    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;
-    }
-    // TODO(ianswett): Move to having the creator flush itself when it's full.
-    packet_creator_.FlushCurrentPacket();
-
-    run_fast_path =
-        !has_handshake && state != FIN_AND_PADDING && !HasPendingFrames() &&
-        write_length - total_bytes_consumed > kMaxOutgoingPacketSize;
-  }
-
-  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) {
-    packet_creator_.FlushCurrentPacket();
-  }
-
-  return QuicConsumedData(total_bytes_consumed, fin_consumed);
-}
-
-QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath(
-    QuicStreamId id,
-    size_t write_length,
-    QuicStreamOffset offset,
-    bool fin,
-    size_t total_bytes_consumed) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.ConsumeDataFastPath(id, write_length, offset, fin,
-                                               total_bytes_consumed);
-  }
-  DCHECK(!QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id));
-
-  while (total_bytes_consumed < write_length &&
-         delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
-                                         NOT_HANDSHAKE)) {
-    // Serialize and encrypt the packet.
-    size_t bytes_consumed = 0;
-    packet_creator_.CreateAndSerializeStreamFrame(
-        id, write_length, total_bytes_consumed, offset + total_bytes_consumed,
-        fin, next_transmission_type_, &bytes_consumed);
-    total_bytes_consumed += bytes_consumed;
-  }
-
-  return QuicConsumedData(total_bytes_consumed,
-                          fin && (total_bytes_consumed == write_length));
-}
-
-void QuicPacketGenerator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.GenerateMtuDiscoveryPacket(target_mtu);
-    return;
-  }
-  // MTU discovery frames must be sent by themselves.
-  if (!packet_creator_.CanSetMaxPacketLength()) {
-    QUIC_BUG << "MTU discovery packets should only be sent when no other "
-             << "frames needs to be sent.";
-    return;
-  }
-  const QuicByteCount current_mtu = GetCurrentMaxPacketLength();
-
-  // 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 =
-      packet_creator_.AddPaddedSavedFrame(frame, next_transmission_type_);
-  packet_creator_.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.
-  DCHECK(success);
-
-  // Reset the packet length back.
-  SetMaxPacketLength(current_mtu);
-}
-
-bool QuicPacketGenerator::PacketFlusherAttached() const {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.PacketFlusherAttached();
-  }
-  return flusher_attached_;
-}
-
-void QuicPacketGenerator::AttachPacketFlusher() {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.AttachPacketFlusher();
-    return;
-  }
-  flusher_attached_ = true;
-  if (!write_start_packet_number_.IsInitialized()) {
-    write_start_packet_number_ = packet_creator_.NextSendingPacketNumber();
-  }
-}
-
-void QuicPacketGenerator::Flush() {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.Flush();
-    return;
-  }
-  packet_creator_.FlushCurrentPacket();
-  SendRemainingPendingPadding();
-  flusher_attached_ = false;
-  if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
-    if (!write_start_packet_number_.IsInitialized()) {
-      QUIC_BUG << "write_start_packet_number is not initialized";
-      return;
-    }
-    QUIC_SERVER_HISTOGRAM_COUNTS(
-        "quic_server_num_written_packets_per_write",
-        packet_creator_.NextSendingPacketNumber() - write_start_packet_number_,
-        1, 200, 50, "Number of QUIC packets written per write operation");
-  }
-  write_start_packet_number_.Clear();
-}
-
-void QuicPacketGenerator::FlushAllQueuedFrames() {
-  packet_creator_.FlushCurrentPacket();
-}
-
-bool QuicPacketGenerator::HasPendingFrames() const {
-  return packet_creator_.HasPendingFrames();
-}
-
-void QuicPacketGenerator::StopSendingVersion() {
-  packet_creator_.StopSendingVersion();
-}
-
-void QuicPacketGenerator::SetDiversificationNonce(
-    const DiversificationNonce& nonce) {
-  packet_creator_.SetDiversificationNonce(nonce);
-}
-
-QuicPacketNumber QuicPacketGenerator::packet_number() const {
-  return packet_creator_.packet_number();
-}
-
-QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const {
-  return packet_creator_.max_packet_length();
-}
-
-void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
-  DCHECK(packet_creator_.CanSetMaxPacketLength());
-  packet_creator_.SetMaxPacketLength(length);
-}
-
-std::unique_ptr<QuicEncryptedPacket>
-QuicPacketGenerator::SerializeVersionNegotiationPacket(
-    bool ietf_quic,
-    bool use_length_prefix,
-    const ParsedQuicVersionVector& supported_versions) {
-  return packet_creator_.SerializeVersionNegotiationPacket(
-      ietf_quic, use_length_prefix, supported_versions);
-}
-
-OwningSerializedPacketPointer
-QuicPacketGenerator::SerializeConnectivityProbingPacket() {
-  return packet_creator_.SerializeConnectivityProbingPacket();
-}
-
-OwningSerializedPacketPointer
-QuicPacketGenerator::SerializePathChallengeConnectivityProbingPacket(
-    QuicPathFrameBuffer* payload) {
-  return packet_creator_.SerializePathChallengeConnectivityProbingPacket(
-      payload);
-}
-
-OwningSerializedPacketPointer
-QuicPacketGenerator::SerializePathResponseConnectivityProbingPacket(
-    const QuicDeque<QuicPathFrameBuffer>& payloads,
-    const bool is_padded) {
-  return packet_creator_.SerializePathResponseConnectivityProbingPacket(
-      payloads, is_padded);
-}
-
-void QuicPacketGenerator::UpdatePacketNumberLength(
-    QuicPacketNumber least_packet_awaited_by_peer,
-    QuicPacketCount max_packets_in_flight) {
-  return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer,
-                                                  max_packets_in_flight);
-}
-
-void QuicPacketGenerator::SkipNPacketNumbers(
-    QuicPacketCount count,
-    QuicPacketNumber least_packet_awaited_by_peer,
-    QuicPacketCount max_packets_in_flight) {
-  packet_creator_.SkipNPacketNumbers(count, least_packet_awaited_by_peer,
-                                     max_packets_in_flight);
-}
-
-void QuicPacketGenerator::SetServerConnectionIdLength(uint32_t length) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.SetServerConnectionIdLength(length);
-    return;
-  }
-  if (length == 0) {
-    packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
-  } else {
-    packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
-  }
-}
-
-void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
-  packet_creator_.set_encryption_level(level);
-}
-
-void QuicPacketGenerator::SetEncrypter(
-    EncryptionLevel level,
-    std::unique_ptr<QuicEncrypter> encrypter) {
-  packet_creator_.SetEncrypter(level, std::move(encrypter));
-}
-
-void QuicPacketGenerator::AddRandomPadding() {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.AddRandomPadding();
-    return;
-  }
-  packet_creator_.AddPendingPadding(
-      random_generator_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
-}
-
-void QuicPacketGenerator::SendRemainingPendingPadding() {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.SendRemainingPendingPadding();
-    return;
-  }
-  while (
-      packet_creator_.pending_padding_bytes() > 0 && !HasPendingFrames() &&
-      delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA, NOT_HANDSHAKE)) {
-    packet_creator_.FlushCurrentPacket();
-  }
-}
-
-bool QuicPacketGenerator::HasRetransmittableFrames() const {
-  return packet_creator_.HasPendingRetransmittableFrames();
-}
-
-bool QuicPacketGenerator::HasPendingStreamFramesOfStream(
-    QuicStreamId id) const {
-  return packet_creator_.HasPendingStreamFramesOfStream(id);
-}
-
-void QuicPacketGenerator::SetTransmissionType(TransmissionType type) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.SetTransmissionType(type);
-    return;
-  }
-  next_transmission_type_ = type;
-}
-
-void QuicPacketGenerator::SetRetryToken(QuicStringPiece retry_token) {
-  packet_creator_.SetRetryToken(retry_token);
-}
-
-MessageStatus QuicPacketGenerator::AddMessageFrame(QuicMessageId message_id,
-                                                   QuicMemSliceSpan message) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.AddMessageFrame(message_id, message);
-  }
-  QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
-                                     "generator tries to add message frame.";
-  MaybeBundleAckOpportunistically();
-  const QuicByteCount message_length = message.total_length();
-  if (message_length > GetCurrentLargestMessagePayload()) {
-    return MESSAGE_STATUS_TOO_LARGE;
-  }
-  if (!packet_creator_.HasRoomForMessageFrame(message_length)) {
-    packet_creator_.FlushCurrentPacket();
-  }
-  QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
-  const bool success =
-      packet_creator_.AddSavedFrame(QuicFrame(frame), next_transmission_type_);
-  if (!success) {
-    QUIC_BUG << "Failed to send message " << message_id;
-    delete frame;
-    return MESSAGE_STATUS_INTERNAL_ERROR;
-  }
-  return MESSAGE_STATUS_SUCCESS;
-}
-
-void QuicPacketGenerator::MaybeBundleAckOpportunistically() {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.MaybeBundleAckOpportunistically();
-    return;
-  }
-  if (packet_creator_.has_ack()) {
-    // Ack already queued, nothing to do.
-    return;
-  }
-  if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                       NOT_HANDSHAKE)) {
-    return;
-  }
-  const bool flushed =
-      FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
-  DCHECK(flushed);
-}
-
-bool QuicPacketGenerator::FlushAckFrame(const QuicFrames& frames) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.FlushAckFrame(frames);
-  }
-  QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
-                                     "generator tries to send ACK frame.";
-  for (const auto& frame : frames) {
-    DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
-    if (packet_creator_.HasPendingFrames()) {
-      if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
-        // There is pending frames and current frame fits.
-        continue;
-      }
-    }
-    DCHECK(!packet_creator_.HasPendingFrames());
-    // 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 =
-        packet_creator_.AddSavedFrame(frame, next_transmission_type_);
-    QUIC_BUG_IF(!success) << "Failed to flush " << frame;
-  }
-  return true;
-}
-
-QuicPacketLength QuicPacketGenerator::GetCurrentLargestMessagePayload() const {
-  return packet_creator_.GetCurrentLargestMessagePayload();
-}
-
-QuicPacketLength QuicPacketGenerator::GetGuaranteedLargestMessagePayload()
-    const {
-  return packet_creator_.GetGuaranteedLargestMessagePayload();
-}
-
-void QuicPacketGenerator::SetServerConnectionId(
-    QuicConnectionId server_connection_id) {
-  packet_creator_.SetServerConnectionId(server_connection_id);
-}
-
-void QuicPacketGenerator::SetClientConnectionId(
-    QuicConnectionId client_connection_id) {
-  packet_creator_.SetClientConnectionId(client_connection_id);
-}
-
-size_t QuicPacketGenerator::SerializeCoalescedPacket(
-    const QuicCoalescedPacket& coalesced,
-    char* buffer,
-    size_t buffer_len) {
-  return packet_creator_.SerializeCoalescedPacket(coalesced, buffer,
-                                                  buffer_len);
-}
-
-void QuicPacketGenerator::SetSoftMaxPacketLength(QuicByteCount length) {
-  packet_creator_.SetSoftMaxPacketLength(length);
-}
-
-void QuicPacketGenerator::set_fully_pad_crypto_handshake_packets(
-    bool new_value) {
-  if (packet_creator_.combine_generator_and_creator()) {
-    packet_creator_.set_fully_pad_crypto_handshake_packets(new_value);
-    return;
-  }
-  fully_pad_crypto_handshake_packets_ = new_value;
-}
-
-bool QuicPacketGenerator::fully_pad_crypto_handshake_packets() const {
-  if (packet_creator_.combine_generator_and_creator()) {
-    return packet_creator_.fully_pad_crypto_handshake_packets();
-  }
-  return fully_pad_crypto_handshake_packets_;
-}
-
-}  // namespace quic
diff --git a/quic/core/quic_packet_generator.h b/quic/core/quic_packet_generator.h
deleted file mode 100644
index efeed75..0000000
--- a/quic/core/quic_packet_generator.h
+++ /dev/null
@@ -1,270 +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 generating packets on behalf of a QuicConnection.
-// Packets are serialized just-in-time.
-// Ack and Feedback frames will be requested from the Connection
-// just-in-time.  When a packet needs to be sent, the Generator
-// will serialize a packet and pass it to QuicConnection::SendOrQueuePacket()
-//
-// The Generator's mode of operation is controlled by two conditions:
-//
-// 1) Is the Delegate writable?
-//
-// If the Delegate is not writable, then no operations will cause
-// a packet to be serialized.  In particular:
-// * SetShouldSendAck will simply record that an ack is to be sent.
-// * AddControlFrame will enqueue the control frame.
-// * ConsumeData will do nothing.
-//
-// If the Delegate is writable, then the behavior depends on the second
-// condition:
-//
-// 2) Is the Generator in batch mode?
-//
-// If the Generator is NOT in batch mode, then each call to a write
-// operation will serialize one or more packets.  The contents will
-// include any previous queued frames.  If an ack should be sent
-// but has not been sent, then the Delegate will be asked to create
-// an Ack frame which will then be included in the packet.  When
-// the write call completes, the current packet will be serialized
-// and sent to the Delegate, even if it is not full.
-//
-// If the Generator is in batch mode, then each write operation will
-// add data to the "current" packet.  When the current packet becomes
-// full, it will be serialized and sent to the packet.  When batch
-// mode is ended via |FinishBatchOperations|, the current packet
-// will be serialzied, even if it is not full.
-
-#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_
-#define QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <list>
-
-#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
-#include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h"
-#include "net/third_party/quiche/src/quic/core/quic_types.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice_span.h"
-
-namespace quic {
-
-namespace test {
-class QuicPacketGeneratorPeer;
-}  // namespace test
-
-class QUIC_EXPORT_PRIVATE QuicPacketGenerator {
- public:
-  QuicPacketGenerator(QuicConnectionId server_connection_id,
-                      QuicFramer* framer,
-                      QuicRandom* random_generator,
-                      QuicPacketCreator::DelegateInterface* delegate);
-  QuicPacketGenerator(const QuicPacketGenerator&) = delete;
-  QuicPacketGenerator& operator=(const QuicPacketGenerator&) = delete;
-
-  ~QuicPacketGenerator();
-
-  // 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);
-
-  // 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);
-
-  // 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);
-
-  // Generates an MTU discovery packet of specified size.
-  void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);
-
-  // Indicates whether packet flusher is currently attached.
-  bool PacketFlusherAttached() const;
-  // Attaches packet flusher.
-  void AttachPacketFlusher();
-  // Flushes everything, including current open packet and pending padding.
-  void Flush();
-
-  // Flushes current open packet.
-  void FlushAllQueuedFrames();
-
-  // Returns true if there are frames pending to be serialized.
-  bool HasPendingFrames() const;
-
-  // 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);
-
-  // Creates a version negotiation packet which supports |supported_versions|.
-  std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
-      bool ietf_quic,
-      bool use_length_prefix,
-      const ParsedQuicVersionVector& supported_versions);
-
-  // Creates a connectivity probing packet.
-  OwningSerializedPacketPointer SerializeConnectivityProbingPacket();
-
-  // Create connectivity probing request and response packets using PATH
-  // CHALLENGE and PATH RESPONSE frames, respectively.
-  // SerializePathChallengeConnectivityProbingPacket will pad the packet to be
-  // MTU bytes long.
-  OwningSerializedPacketPointer SerializePathChallengeConnectivityProbingPacket(
-      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.
-  OwningSerializedPacketPointer SerializePathResponseConnectivityProbingPacket(
-      const QuicDeque<QuicPathFrameBuffer>& payloads,
-      const bool is_padded);
-
-  // Update the packet number length to use in future packets as soon as it
-  // can be safely changed.
-  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);
-
-  // Set the minimum number of bytes for the server connection id length;
-  void SetServerConnectionIdLength(uint32_t length);
-
-  // Sets the encrypter to use for the encryption level.
-  void SetEncrypter(EncryptionLevel level,
-                    std::unique_ptr<QuicEncrypter> encrypter);
-
-  // Returns true if there are control frames or current constructed packet has
-  // pending retransmittable frames.
-  bool HasRetransmittableFrames() const;
-
-  // Returns true if current constructed packet has pending stream frames for
-  // stream |id|.
-  bool HasPendingStreamFramesOfStream(QuicStreamId id) const;
-
-  // Sets the encryption level that will be applied to new packets.
-  void set_encryption_level(EncryptionLevel level);
-
-  // packet number of the last created packet, or 0 if no packets have been
-  // created.
-  QuicPacketNumber packet_number() const;
-
-  // Returns the maximum length a current packet can actually have.
-  QuicByteCount GetCurrentMaxPacketLength() const;
-
-  // Set maximum packet length in the creator immediately.  May not be called
-  // when there are frames queued in the creator.
-  void SetMaxPacketLength(QuicByteCount length);
-
-  // Set transmission type of next constructed packets.
-  void SetTransmissionType(TransmissionType type);
-
-  // Sets the retry token to be sent over the wire in IETF Initial packets.
-  void SetRetryToken(QuicStringPiece retry_token);
-
-  // Tries to add a message frame containing |message| and returns the status.
-  MessageStatus AddMessageFrame(QuicMessageId message_id,
-                                QuicMemSliceSpan message);
-
-  // Called to flush ACK and STOP_WAITING frames, returns false if the flush
-  // fails.
-  bool FlushAckFrame(const QuicFrames& frames);
-
-  // Returns the largest payload that will fit into a single MESSAGE frame.
-  QuicPacketLength GetCurrentLargestMessagePayload() const;
-  QuicPacketLength GetGuaranteedLargestMessagePayload() const;
-
-  // 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);
-
-  // 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);
-
-  // 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);
-
-  void set_debug_delegate(QuicPacketCreator::DebugDelegate* debug_delegate) {
-    packet_creator_.set_debug_delegate(debug_delegate);
-  }
-
-  void set_fully_pad_crypto_handshake_packets(bool new_value);
-
-  bool fully_pad_crypto_handshake_packets() const;
-
- private:
-  friend class test::QuicPacketGeneratorPeer;
-
-  // Adds a random amount of padding (between 1 to 256 bytes).
-  void AddRandomPadding();
-
-  // Sends remaining pending padding.
-  // Pending paddings should only be sent when there is nothing else to send.
-  void SendRemainingPendingPadding();
-
-  // Called when there is data to be sent, Retrieves updated ACK frame from
-  // delegate_ and flushes it.
-  void MaybeBundleAckOpportunistically();
-
-  QuicPacketCreator::DelegateInterface* delegate_;
-
-  QuicPacketCreator packet_creator_;
-
-  // Transmission type of the next serialized packet.
-  TransmissionType next_transmission_type_;
-
-  // True if packet flusher is currently attached.
-  bool flusher_attached_;
-
-  QuicRandom* random_generator_;
-
-  // 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_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CORE_QUIC_PACKET_GENERATOR_H_
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
deleted file mode 100644
index 7a7701e..0000000
--- a/quic/core/quic_packet_generator_test.cc
+++ /dev/null
@@ -1,1511 +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 "net/third_party/quiche/src/quic/core/quic_packet_generator.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
-#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
-#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
-#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
-#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
-#include "net/third_party/quiche/src/quic/core/quic_simple_buffer_allocator.h"
-#include "net/third_party/quiche/src/quic/core/quic_utils.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
-#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
-#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
-#include "net/third_party/quiche/src/quic/test_tools/simple_quic_framer.h"
-
-using testing::_;
-using testing::InSequence;
-using testing::Return;
-using testing::StrictMock;
-
-namespace quic {
-namespace test {
-namespace {
-
-class MockDelegate : public QuicPacketCreator::DelegateInterface {
- public:
-  MockDelegate() {}
-  MockDelegate(const MockDelegate&) = delete;
-  MockDelegate& operator=(const MockDelegate&) = delete;
-  ~MockDelegate() override {}
-
-  MOCK_METHOD2(ShouldGeneratePacket,
-               bool(HasRetransmittableData retransmittable,
-                    IsHandshake handshake));
-  MOCK_METHOD0(MaybeBundleAckOpportunistically, const QuicFrames());
-  MOCK_METHOD0(GetPacketBuffer, char*());
-  MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
-  MOCK_METHOD2(OnUnrecoverableError, void(QuicErrorCode, const std::string&));
-
-  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;
-};
-
-}  // namespace
-
-class TestPacketGenerator : public QuicPacketGenerator {
- public:
-  TestPacketGenerator(QuicConnectionId connection_id,
-                      QuicFramer* framer,
-                      QuicRandom* random_generator,
-                      QuicPacketCreator::DelegateInterface* delegate,
-                      SimpleDataProducer* producer)
-      : QuicPacketGenerator(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 (!QuicPacketGeneratorPeer::GetPacketCreator(this)->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 QuicPacketGenerator::ConsumeRetransmittableControlFrame(frame);
-  }
-
-  QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
-                                       const struct iovec* iov,
-                                       int iov_count,
-                                       size_t total_length,
-                                       QuicStreamOffset offset,
-                                       bool fin) {
-    // Save data before data is consumed.
-    if (total_length > 0) {
-      producer_->SaveStreamData(id, iov, iov_count, 0, total_length);
-    }
-    return QuicPacketGenerator::ConsumeDataFastPath(id, total_length, offset,
-                                                    fin, 0);
-  }
-
-  QuicConsumedData ConsumeData(QuicStreamId id,
-                               const struct iovec* iov,
-                               int iov_count,
-                               size_t total_length,
-                               QuicStreamOffset offset,
-                               StreamSendingState state) {
-    // Save data before data is consumed.
-    if (total_length > 0) {
-      producer_->SaveStreamData(id, iov, iov_count, 0, total_length);
-    }
-    if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack() &&
-        delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                        NOT_HANDSHAKE)) {
-      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
-    }
-    return QuicPacketGenerator::ConsumeData(id, total_length, offset, state);
-  }
-
-  MessageStatus AddMessageFrame(QuicMessageId message_id,
-                                QuicMemSliceSpan message) {
-    if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack() &&
-        delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                        NOT_HANDSHAKE)) {
-      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
-    }
-    return QuicPacketGenerator::AddMessageFrame(message_id, message);
-  }
-
-  size_t ConsumeCryptoData(EncryptionLevel level,
-                           QuicStringPiece data,
-                           QuicStreamOffset offset) {
-    producer_->SaveCryptoData(level, offset, data);
-    if (!QuicPacketGeneratorPeer::GetPacketCreator(this)->has_ack() &&
-        delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
-                                        NOT_HANDSHAKE)) {
-      EXPECT_CALL(*delegate_, MaybeBundleAckOpportunistically()).Times(1);
-    }
-    return QuicPacketGenerator::ConsumeCryptoData(level, data.length(), offset);
-  }
-
-  QuicAckFrame ack_frame_;
-  MockDelegate* delegate_;
-  SimpleDataProducer* producer_;
-};
-
-class QuicPacketGeneratorTest : public QuicTest {
- public:
-  QuicPacketGeneratorTest()
-      : framer_(AllSupportedVersions(),
-                QuicTime::Zero(),
-                Perspective::IS_CLIENT,
-                kQuicDefaultConnectionIdLength),
-        generator_(TestConnectionId(),
-                   &framer_,
-                   &random_generator_,
-                   &delegate_,
-                   &producer_),
-        creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)),
-        ack_frame_(InitAckFrame(1)) {
-    EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr));
-    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));
-    }
-    generator_.AttachPacketFlusher();
-  }
-
-  ~QuicPacketGeneratorTest() override {
-    for (SerializedPacket& packet : packets_) {
-      delete[] packet.encrypted_buffer;
-      ClearSerializedPacket(&packet);
-    }
-  }
-
-  void SavePacket(SerializedPacket* packet) {
-    packet->encrypted_buffer = CopyBuffer(*packet);
-    packets_.push_back(*packet);
-    packet->encrypted_buffer = nullptr;
-    packet->retransmittable_frames.clear();
-  }
-
- 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);
-    }
-  }
-
-  void CreateData(size_t len) {
-    data_array_.reset(new char[len]);
-    memset(data_array_.get(), '?', len);
-    iov_.iov_base = data_array_.get();
-    iov_.iov_len = len;
-  }
-
-  QuicFramer framer_;
-  MockRandom random_generator_;
-  StrictMock<MockDelegate> delegate_;
-  TestPacketGenerator generator_;
-  QuicPacketCreator* creator_;
-  SimpleQuicFramer simple_framer_;
-  std::vector<SerializedPacket> packets_;
-  QuicAckFrame ack_frame_;
-  struct iovec iov_;
-  SimpleBufferAllocator allocator_;
-
- private:
-  std::unique_ptr<char[]> data_array_;
-  SimpleDataProducer producer_;
-};
-
-class MockDebugDelegate : public QuicPacketCreator::DebugDelegate {
- public:
-  MOCK_METHOD1(OnFrameAddedToPacket, void(const QuicFrame&));
-};
-
-TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/false);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-  delete rst_frame;
-}
-
-TEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
-  delegate_.SetCanWriteOnlyNonRetransmittable();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/false);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-  delete rst_frame;
-}
-
-TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
-  delegate_.SetCanWriteAnything();
-
-  generator_.ConsumeRetransmittableControlFrame(
-      QuicFrame(CreateRstStreamFrame()),
-      /*bundle_ack=*/false);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-}
-
-TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/false);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-  delete rst_frame;
-}
-
-TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-
-  generator_.ConsumeRetransmittableControlFrame(
-      QuicFrame(CreateRstStreamFrame()),
-      /*bundle_ack=*/false);
-  generator_.Flush();
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_rst_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketGeneratorTest, ConsumeCryptoData) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  std::string data = "crypto data";
-  size_t consumed_bytes =
-      generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  generator_.Flush();
-  EXPECT_EQ(data.length(), consumed_bytes);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_crypto_frames = 1;
-  contents.num_padding_frames = 1;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
-  delegate_.SetCanNotWrite();
-
-  MakeIOVector("foo", &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  EXPECT_EQ(0u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-}
-
-TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
-  delegate_.SetCanWriteAnything();
-
-  MakeIOVector("foo", &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-}
-
-TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  MakeIOVector("foo", &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  generator_.Flush();
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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 generator operates in batch mode.
-TEST_F(QuicPacketGeneratorTest, ConsumeData_Handshake) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  std::string data = "foo bar";
-  MakeIOVector(data, &iov_);
-  size_t consumed_bytes = 0;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    consumed_bytes = generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  } else {
-    consumed_bytes =
-        generator_
-            .ConsumeData(
-                QuicUtils::GetCryptoStreamId(framer_.transport_version()),
-                &iov_, 1u, iov_.iov_len, 0, NO_FIN)
-            .bytes_consumed;
-  }
-  EXPECT_EQ(7u, consumed_bytes);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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, generator_.GetCurrentMaxPacketLength());
-  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(QuicPacketGeneratorTest, ConsumeData_Handshake_PaddingDisabled) {
-  generator_.set_fully_pad_crypto_handshake_packets(false);
-
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  std::string data = "foo";
-  MakeIOVector(data, &iov_);
-  size_t bytes_consumed = 0;
-  if (QuicVersionUsesCryptoFrames(framer_.transport_version())) {
-    bytes_consumed = generator_.ConsumeCryptoData(ENCRYPTION_INITIAL, data, 0);
-  } else {
-    bytes_consumed =
-        generator_
-            .ConsumeData(
-                QuicUtils::GetCryptoStreamId(framer_.transport_version()),
-                &iov_, 1u, iov_.iov_len, 0, NO_FIN)
-            .bytes_consumed;
-  }
-  EXPECT_EQ(3u, bytes_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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, generator_.GetCurrentMaxPacketLength());
-  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(QuicPacketGeneratorTest, ConsumeData_EmptyData) {
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_QUIC_BUG(generator_.ConsumeData(
-                      QuicUtils::QuicUtils::GetFirstBidirectionalStreamId(
-                          framer_.transport_version(), Perspective::IS_CLIENT),
-                      nullptr, 0, 0, 0, NO_FIN),
-                  "Attempt to consume empty data without FIN.");
-}
-
-TEST_F(QuicPacketGeneratorTest,
-       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
-  delegate_.SetCanWriteAnything();
-
-  MakeIOVector("foo", &iov_);
-  generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  MakeIOVector("quux", &iov_);
-  QuicConsumedData consumed =
-      generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 3, NO_FIN);
-  EXPECT_EQ(4u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-}
-
-TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
-  delegate_.SetCanWriteAnything();
-
-  MakeIOVector("foo", &iov_);
-  generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, NO_FIN);
-  MakeIOVector("quux", &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 3, FIN);
-  EXPECT_EQ(4u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  // Now both frames will be flushed out.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  generator_.Flush();
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames =
-      GetQuicReloadableFlag(quic_coalesce_stream_frames) ? 1 : 2;
-  CheckPacketContains(contents, 0);
-}
-
-TEST_F(QuicPacketGeneratorTest, 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;
-  generator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  {
-    InSequence dummy;
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  }
-  // Queue enough data to prevent a stream frame with a non-zero offset from
-  // fitting.
-  MakeIOVector("foo", &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, NO_FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  // 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.
-  MakeIOVector("bar", &iov_);
-  consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 3, FIN);
-  EXPECT_EQ(3u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  creator_->FlushCurrentPacket();
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  PacketContents contents;
-  contents.num_stream_frames = 1;
-  CheckPacketContains(contents, 0);
-  CheckPacketContains(contents, 1);
-}
-
-TEST_F(QuicPacketGeneratorTest, ConsumeDataFastPath) {
-  delegate_.SetCanWriteAnything();
-  generator_.SetTransmissionType(LOSS_RETRANSMISSION);
-
-  // Create a 10000 byte IOVector.
-  CreateData(10000);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  QuicConsumedData consumed = generator_.ConsumeDataFastPath(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, true);
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest, ConsumeDataLarge) {
-  delegate_.SetCanWriteAnything();
-
-  // Create a 10000 byte IOVector.
-  CreateData(10000);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest, ConsumeDataLargeSendAckFalse) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool success =
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/true);
-  EXPECT_FALSE(success);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  delegate_.SetCanWriteAnything();
-
-  generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                /*bundle_ack=*/false);
-
-  // Create a 10000 byte IOVector.
-  CreateData(10000);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  generator_.ConsumeRetransmittableControlFrame(
-      QuicFrame(CreateRstStreamFrame()),
-      /*bundle_ack=*/true);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  generator_.Flush();
-
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest, ConsumeDataLargeSendAckTrue) {
-  if (VersionHasIetfInvariantHeader(framer_.transport_version())) {
-    return;
-  }
-  delegate_.SetCanNotWrite();
-  delegate_.SetCanWriteAnything();
-
-  // Create a 10000 byte IOVector.
-  CreateData(10000);
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  generator_.Flush();
-
-  EXPECT_EQ(10000u, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool consumed =
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/true);
-  EXPECT_FALSE(consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-  EXPECT_FALSE(generator_.HasPendingStreamFramesOfStream(3));
-
-  delegate_.SetCanWriteAnything();
-
-  EXPECT_TRUE(
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/false));
-  // Send some data and a control frame
-  MakeIOVector("quux", &iov_);
-  generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, NO_FIN);
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    generator_.ConsumeRetransmittableControlFrame(
-        QuicFrame(CreateGoAwayFrame()),
-        /*bundle_ack=*/false);
-  }
-  EXPECT_TRUE(generator_.HasPendingStreamFramesOfStream(3));
-
-  // All five frames will be flushed out in a single packet.
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  generator_.Flush();
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-  EXPECT_FALSE(generator_.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(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
-  delegate_.SetCanNotWrite();
-
-  QuicRstStreamFrame* rst_frame = CreateRstStreamFrame();
-  const bool success =
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/true);
-  EXPECT_FALSE(success);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  delegate_.SetCanWriteAnything();
-
-  {
-    InSequence dummy;
-    // All five frames will be flushed out in a single packet
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-    EXPECT_CALL(delegate_, OnSerializedPacket(_))
-        .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  }
-  EXPECT_TRUE(
-      generator_.ConsumeRetransmittableControlFrame(QuicFrame(rst_frame),
-                                                    /*bundle_ack=*/false));
-  // Send enough data to exceed one packet
-  size_t data_len = kDefaultMaxPacketSize + 100;
-  CreateData(data_len);
-  QuicConsumedData consumed =
-      generator_.ConsumeData(3, &iov_, 1u, iov_.iov_len, 0, FIN);
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  if (!VersionHasIetfQuicFrames(framer_.transport_version())) {
-    generator_.ConsumeRetransmittableControlFrame(
-        QuicFrame(CreateGoAwayFrame()),
-        /*bundle_ack=*/false);
-  }
-
-  generator_.Flush();
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // 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(QuicPacketGeneratorTest, PacketTransmissionType) {
-  delegate_.SetCanWriteAnything();
-
-  // The first ConsumeData will fill the packet without flush.
-  generator_.SetTransmissionType(LOSS_RETRANSMISSION);
-
-  size_t data_len = 1324;
-  CreateData(data_len);
-  QuicStreamId stream1_id = QuicUtils::GetFirstBidirectionalStreamId(
-      framer_.transport_version(), Perspective::IS_CLIENT);
-  QuicConsumedData consumed =
-      generator_.ConsumeData(stream1_id, &iov_, 1u, iov_.iov_len, 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.
-  generator_.SetTransmissionType(NOT_RETRANSMISSION);
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-
-  QuicStreamId stream2_id = stream1_id + 4;
-
-  consumed =
-      generator_.ConsumeData(stream2_id, &iov_, 1u, iov_.iov_len, 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(QuicPacketGeneratorTest, TestConnectionIdLength) {
-  QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_SERVER);
-  generator_.SetServerConnectionIdLength(0);
-  EXPECT_EQ(PACKET_0BYTE_CONNECTION_ID,
-            creator_->GetDestinationConnectionIdLength());
-
-  for (size_t i = 1; i < 10; i++) {
-    generator_.SetServerConnectionIdLength(i);
-    if (VersionHasIetfInvariantHeader(framer_.transport_version())) {
-      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(QuicPacketGeneratorTest, 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);
-  generator_.SetMaxPacketLength(packet_len);
-  EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
-
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .Times(3)
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  CreateData(data_len);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len,
-      /*offset=*/0, FIN);
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // 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
-  // generator 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(QuicPacketGeneratorTest, 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, &QuicPacketGeneratorTest::SavePacket));
-
-  // Send two packets before packet size change.
-  CreateData(data_len);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len,
-      /*offset=*/0, NO_FIN);
-  generator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // Make sure we already have two packets.
-  ASSERT_EQ(2u, packets_.size());
-
-  // Increase packet size.
-  generator_.SetMaxPacketLength(packet_len);
-  EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
-
-  // Send a packet after packet size change.
-  CreateData(data_len);
-  generator_.AttachPacketFlusher();
-  consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, data_len, FIN);
-  generator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // 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(QuicPacketGeneratorTest, 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.
-  CreateData(first_write_len);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len,
-      /*offset=*/0, NO_FIN);
-  EXPECT_EQ(first_write_len, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  // 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, &QuicPacketGeneratorTest::SavePacket));
-
-  // Increase packet size after flushing all frames.
-  // Ensure it's immediately enacted.
-  generator_.FlushAllQueuedFrames();
-  generator_.SetMaxPacketLength(packet_len);
-  EXPECT_EQ(packet_len, generator_.GetCurrentMaxPacketLength());
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // 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, &QuicPacketGeneratorTest::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.
-  CreateData(second_write_len);
-  consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len,
-      /*offset=*/first_write_len, FIN);
-  EXPECT_EQ(second_write_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  // 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(QuicPacketGeneratorTest, GenerateConnectivityProbingPacket) {
-  delegate_.SetCanWriteAnything();
-
-  OwningSerializedPacketPointer probing_packet;
-  if (VersionHasIetfQuicFrames(framer_.transport_version())) {
-    QuicPathFrameBuffer payload = {
-        {0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe}};
-    probing_packet =
-        generator_.SerializePathChallengeConnectivityProbingPacket(&payload);
-  } else {
-    probing_packet = generator_.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(QuicPacketGeneratorTest, 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, &QuicPacketGeneratorTest::SavePacket));
-
-  generator_.GenerateMtuDiscoveryPacket(target_mtu);
-
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-  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(QuicPacketGeneratorTest, 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, &QuicPacketGeneratorTest::SavePacket));
-
-  // Send data before the MTU probe.
-  CreateData(data_len);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len,
-      /*offset=*/0, NO_FIN);
-  generator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_FALSE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // Send the MTU probe.
-  generator_.GenerateMtuDiscoveryPacket(target_mtu);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  // Send data after the MTU probe.
-  CreateData(data_len);
-  generator_.AttachPacketFlusher();
-  consumed = generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len,
-      /*offset=*/data_len, FIN);
-  generator_.Flush();
-  EXPECT_EQ(data_len, consumed.bytes_consumed);
-  EXPECT_TRUE(consumed.fin_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest, DontCrashOnInvalidStopWaiting) {
-  if (VersionSupportsMessageFrames(framer_.transport_version())) {
-    return;
-  }
-  // Test added to ensure the generator 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(generator_.Flush(),
-                  "packet_number_length 1 is too small "
-                  "for least_unacked_delta: 1001");
-}
-
-// Regression test for b/31486443.
-TEST_F(QuicPacketGeneratorTest, ConnectionCloseFrameLargerThanPacketSize) {
-  delegate_.SetCanWriteAnything();
-  char buf[2000] = {};
-  QuicStringPiece error_details(buf, 2000);
-  const QuicErrorCode kQuicErrorCode = QUIC_PACKET_WRITE_ERROR;
-
-  QuicConnectionCloseFrame* frame = new QuicConnectionCloseFrame(
-      framer_.transport_version(), kQuicErrorCode, std::string(error_details),
-      /*transport_close_frame_type=*/0);
-  generator_.ConsumeRetransmittableControlFrame(QuicFrame(frame),
-                                                /*bundle_ack=*/false);
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-}
-
-TEST_F(QuicPacketGeneratorTest, 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;
-  generator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
-  generator_.Flush();
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest,
-       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;
-  generator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      kDataStreamId, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
-  generator_.Flush();
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest,
-       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;
-  generator_.SetMaxPacketLength(length);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillRepeatedly(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
-  QuicConsumedData consumed = generator_.ConsumeData(
-      kDataStreamId1, &iov_, 1u, iov_.iov_len, 0, FIN_AND_PADDING);
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  MakeIOVector(QuicStringPiece(buf, kStreamFramePayloadSize), &iov_);
-  consumed = generator_.ConsumeData(kDataStreamId2, &iov_, 1u, iov_.iov_len, 0,
-                                    FIN_AND_PADDING);
-  EXPECT_EQ(kStreamFramePayloadSize, consumed.bytes_consumed);
-  generator_.Flush();
-  EXPECT_FALSE(generator_.HasPendingFrames());
-  EXPECT_FALSE(generator_.HasRetransmittableFrames());
-
-  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(QuicPacketGeneratorTest, AddMessageFrame) {
-  if (!VersionSupportsMessageFrames(framer_.transport_version())) {
-    return;
-  }
-  quic::QuicMemSliceStorage storage(nullptr, 0, nullptr, 0);
-  delegate_.SetCanWriteAnything();
-  EXPECT_CALL(delegate_, OnSerializedPacket(_))
-      .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
-
-  MakeIOVector("foo", &iov_);
-  generator_.ConsumeData(
-      QuicUtils::GetFirstBidirectionalStreamId(framer_.transport_version(),
-                                               Perspective::IS_CLIENT),
-      &iov_, 1u, iov_.iov_len, 0, FIN);
-  EXPECT_EQ(MESSAGE_STATUS_SUCCESS,
-            generator_.AddMessageFrame(
-                1, MakeSpan(&allocator_, "message", &storage)));
-  EXPECT_TRUE(generator_.HasPendingFrames());
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  // Add a message which causes the flush of current packet.
-  EXPECT_EQ(
-      MESSAGE_STATUS_SUCCESS,
-      generator_.AddMessageFrame(
-          2, MakeSpan(
-                 &allocator_,
-                 std::string(generator_.GetCurrentLargestMessagePayload(), 'a'),
-                 &storage)));
-  EXPECT_TRUE(generator_.HasRetransmittableFrames());
-
-  // Failed to send messages which cannot fit into one packet.
-  EXPECT_EQ(
-      MESSAGE_STATUS_TOO_LARGE,
-      generator_.AddMessageFrame(
-          3,
-          MakeSpan(&allocator_,
-                   std::string(
-                       generator_.GetCurrentLargestMessagePayload() + 10, 'a'),
-                   &storage)));
-}
-
-TEST_F(QuicPacketGeneratorTest, ConnectionId) {
-  generator_.SetServerConnectionId(TestConnectionId(0x1337));
-  EXPECT_EQ(TestConnectionId(0x1337), creator_->GetDestinationConnectionId());
-  EXPECT_EQ(EmptyQuicConnectionId(), creator_->GetSourceConnectionId());
-  if (!framer_.version().SupportsClientConnectionIds()) {
-    return;
-  }
-  generator_.SetClientConnectionId(TestConnectionId(0x33));
-  EXPECT_EQ(TestConnectionId(0x1337), creator_->GetDestinationConnectionId());
-  EXPECT_EQ(TestConnectionId(0x33), creator_->GetSourceConnectionId());
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/quartc/quartc_packet_writer.cc b/quic/quartc/quartc_packet_writer.cc
index 5ffb892..f67cc77 100644
--- a/quic/quartc/quartc_packet_writer.cc
+++ b/quic/quartc/quartc_packet_writer.cc
@@ -29,7 +29,7 @@
       static_cast<QuartcPerPacketOptions*>(options);
   if (quartc_options && quartc_options->connection) {
     info.packet_number =
-        quartc_options->connection->packet_generator().packet_number();
+        quartc_options->connection->packet_creator().packet_number();
   }
   int bytes_written = packet_transport_->Write(buffer, buf_len, info);
   if (bytes_written <= 0) {
diff --git a/quic/test_tools/quic_connection_peer.cc b/quic/test_tools/quic_connection_peer.cc
index f2f1f2f..197514e 100644
--- a/quic/test_tools/quic_connection_peer.cc
+++ b/quic/test_tools/quic_connection_peer.cc
@@ -9,7 +9,6 @@
 #include "net/third_party/quiche/src/quic/core/quic_received_packet_manager.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_framer_peer.h"
-#include "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
 
 namespace quic {
@@ -39,14 +38,7 @@
 // static
 QuicPacketCreator* QuicConnectionPeer::GetPacketCreator(
     QuicConnection* connection) {
-  return QuicPacketGeneratorPeer::GetPacketCreator(
-      &connection->packet_generator_);
-}
-
-// static
-QuicPacketGenerator* QuicConnectionPeer::GetPacketGenerator(
-    QuicConnection* connection) {
-  return &connection->packet_generator_;
+  return &connection->packet_creator_;
 }
 
 // static
diff --git a/quic/test_tools/quic_connection_peer.h b/quic/test_tools/quic_connection_peer.h
index 04d7826..8eb1c40 100644
--- a/quic/test_tools/quic_connection_peer.h
+++ b/quic/test_tools/quic_connection_peer.h
@@ -20,7 +20,6 @@
 class QuicEncryptedPacket;
 class QuicFramer;
 class QuicPacketCreator;
-class QuicPacketGenerator;
 class QuicPacketWriter;
 class QuicSentPacketManager;
 class SendAlgorithmInterface;
@@ -43,8 +42,6 @@
 
   static QuicPacketCreator* GetPacketCreator(QuicConnection* connection);
 
-  static QuicPacketGenerator* GetPacketGenerator(QuicConnection* connection);
-
   static QuicSentPacketManager* GetSentPacketManager(
       QuicConnection* connection);
 
diff --git a/quic/test_tools/quic_packet_generator_peer.cc b/quic/test_tools/quic_packet_generator_peer.cc
deleted file mode 100644
index 91a8752..0000000
--- a/quic/test_tools/quic_packet_generator_peer.cc
+++ /dev/null
@@ -1,20 +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 "net/third_party/quiche/src/quic/test_tools/quic_packet_generator_peer.h"
-
-#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
-#include "net/third_party/quiche/src/quic/core/quic_packet_generator.h"
-
-namespace quic {
-namespace test {
-
-// static
-QuicPacketCreator* QuicPacketGeneratorPeer::GetPacketCreator(
-    QuicPacketGenerator* generator) {
-  return &generator->packet_creator_;
-}
-
-}  // namespace test
-}  // namespace quic
diff --git a/quic/test_tools/quic_packet_generator_peer.h b/quic/test_tools/quic_packet_generator_peer.h
deleted file mode 100644
index 6941b08..0000000
--- a/quic/test_tools/quic_packet_generator_peer.h
+++ /dev/null
@@ -1,28 +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_PACKET_GENERATOR_PEER_H_
-#define QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_
-
-#include "net/third_party/quiche/src/quic/core/quic_packets.h"
-
-namespace quic {
-
-class QuicPacketCreator;
-class QuicPacketGenerator;
-
-namespace test {
-
-class QuicPacketGeneratorPeer {
- public:
-  QuicPacketGeneratorPeer() = delete;
-
-  static QuicPacketCreator* GetPacketCreator(QuicPacketGenerator* generator);
-};
-
-}  // namespace test
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_TEST_TOOLS_QUIC_PACKET_GENERATOR_PEER_H_
