Update from chromium https://crrev.com/304586

Review URL: https://codereview.chromium.org/732423002
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 3bd06bc..be0ac53 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -473,6 +473,8 @@
     # doesn't set USE_NSS but needs some of the files.
     set_sources_assignment_filter([])
     sources += [
+      "base/net_util_mac.cc",
+      "base/net_util_mac.h",
       "base/network_change_notifier_mac.cc",
       "base/network_config_watcher_mac.cc",
       "base/platform_mime_util_mac.mm",
@@ -506,6 +508,8 @@
       "base/platform_mime_util_linux.cc",
       "base/address_tracker_linux.cc",
       "base/address_tracker_linux.h",
+      "base/net_util_linux.cc",
+      "base/net_util_linux.h"
     ]
     set_sources_assignment_filter(sources_assignment_filter)
 
diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc
index 6675692..18cf9f5 100644
--- a/net/base/host_port_pair.cc
+++ b/net/base/host_port_pair.cc
@@ -10,6 +10,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "net/base/ip_endpoint.h"
+#include "net/base/net_util.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -36,7 +37,8 @@
   int port;
   if (!base::StringToInt(key_port[1], &port))
     return HostPortPair();
-  DCHECK_LT(port, 1 << 16);
+  if (!IsPortValid(port))
+    return HostPortPair();
   HostPortPair host_port_pair;
   host_port_pair.set_host(key_port[0]);
   host_port_pair.set_port(port);
diff --git a/net/base/host_port_pair_unittest.cc b/net/base/host_port_pair_unittest.cc
index 5b15db9..2c97e94 100644
--- a/net/base/host_port_pair_unittest.cc
+++ b/net/base/host_port_pair_unittest.cc
@@ -37,13 +37,19 @@
 }
 
 TEST(HostPortPairTest, BadString) {
-  HostPortPair foo = HostPortPair::FromString("foo.com:2:3");
-  EXPECT_TRUE(foo.host().empty());
-  EXPECT_EQ(0, foo.port());
+  const char* kBadStrings[] = {
+    "foo.com:2:3",
+    "bar.com:two",
+    "www.google.com:-1",
+    "127.0.0.1:65536",
+    "[2001:db8::42]:65536",
+  };
 
-  HostPortPair bar = HostPortPair::FromString("bar.com:two");
-  EXPECT_TRUE(bar.host().empty());
-  EXPECT_EQ(0, bar.port());
+  for (size_t index = 0; index < arraysize(kBadStrings); ++index) {
+    HostPortPair foo = HostPortPair::FromString(kBadStrings[index]);
+    EXPECT_TRUE(foo.host().empty());
+    EXPECT_EQ(0, foo.port());
+  }
 }
 
 TEST(HostPortPairTest, Emptiness) {
diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h
index 6e49bbb..2754326 100644
--- a/net/base/load_flags_list.h
+++ b/net/base/load_flags_list.h
@@ -34,94 +34,90 @@
 // impact the HTTP request headers.
 LOAD_FLAG(DISABLE_CACHE, 1 << 5)
 
-// This is a navigation that will not be intercepted by any registered
-// URLRequest::Interceptors.
-LOAD_FLAG(DISABLE_INTERCEPT, 1 << 6)
-
 // If present, ignores certificate mismatches with the domain name.
 // (The default behavior is to trigger an OnSSLCertificateError callback.)
-LOAD_FLAG(IGNORE_CERT_COMMON_NAME_INVALID, 1 << 7)
+LOAD_FLAG(IGNORE_CERT_COMMON_NAME_INVALID, 1 << 6)
 
 // If present, ignores certificate expiration dates
 // (The default behavior is to trigger an OnSSLCertificateError callback).
-LOAD_FLAG(IGNORE_CERT_DATE_INVALID, 1 << 8)
+LOAD_FLAG(IGNORE_CERT_DATE_INVALID, 1 << 7)
 
 // If present, trusts all certificate authorities
 // (The default behavior is to trigger an OnSSLCertificateError callback).
-LOAD_FLAG(IGNORE_CERT_AUTHORITY_INVALID, 1 << 9)
+LOAD_FLAG(IGNORE_CERT_AUTHORITY_INVALID, 1 << 8)
 
 // If present, causes certificate revocation checks to be skipped on secure
 // connections.
-LOAD_FLAG(DISABLE_CERT_REVOCATION_CHECKING, 1 << 10)
+LOAD_FLAG(DISABLE_CERT_REVOCATION_CHECKING, 1 << 9)
 
 // If present, ignores wrong key usage of the certificate
 // (The default behavior is to trigger an OnSSLCertificateError callback).
-LOAD_FLAG(IGNORE_CERT_WRONG_USAGE, 1 << 11)
+LOAD_FLAG(IGNORE_CERT_WRONG_USAGE, 1 << 10)
 
 // This load will not make any changes to cookies, including storing new
 // cookies or updating existing ones.
-LOAD_FLAG(DO_NOT_SAVE_COOKIES, 1 << 12)
+LOAD_FLAG(DO_NOT_SAVE_COOKIES, 1 << 11)
 
 // Do not resolve proxies. This override is used when downloading PAC files
 // to avoid having a circular dependency.
-LOAD_FLAG(BYPASS_PROXY, 1 << 13)
+LOAD_FLAG(BYPASS_PROXY, 1 << 12)
 
 // Indicate this request is for a download, as opposed to viewing.
-LOAD_FLAG(IS_DOWNLOAD, 1 << 14)
+LOAD_FLAG(IS_DOWNLOAD, 1 << 13)
 
 // Requires EV certificate verification.
-LOAD_FLAG(VERIFY_EV_CERT, 1 << 15)
+LOAD_FLAG(VERIFY_EV_CERT, 1 << 14)
 
 // This load will not send any cookies.
-LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 16)
+LOAD_FLAG(DO_NOT_SEND_COOKIES, 1 << 15)
 
 // This load will not send authentication data (user name/password)
 // to the server (as opposed to the proxy).
-LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 17)
+LOAD_FLAG(DO_NOT_SEND_AUTH_DATA, 1 << 16)
 
 // This should only be used for testing (set by HttpNetworkTransaction).
-LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 18)
+LOAD_FLAG(IGNORE_ALL_CERT_ERRORS, 1 << 17)
 
 // Indicate that this is a top level frame, so that we don't assume it is a
 // subresource and speculatively pre-connect or pre-resolve when a referring
 // page is loaded.
-LOAD_FLAG(MAIN_FRAME, 1 << 19)
+LOAD_FLAG(MAIN_FRAME, 1 << 18)
 
 // Indicate that this is a sub frame, and hence it might have subresources that
 // should be speculatively resolved, or even speculatively preconnected.
-LOAD_FLAG(SUB_FRAME, 1 << 20)
+LOAD_FLAG(SUB_FRAME, 1 << 19)
 
 // If present, intercept actual request/response headers from network stack
 // and report them to renderer. This includes cookies, so the flag is only
 // respected if renderer has CanReadRawCookies capability in the security
 // policy.
-LOAD_FLAG(REPORT_RAW_HEADERS, 1 << 21)
+LOAD_FLAG(REPORT_RAW_HEADERS, 1 << 20)
 
 // Indicates that this load was motivated by the rel=prefetch feature,
 // and is (in theory) not intended for the current frame.
-LOAD_FLAG(PREFETCH, 1 << 22)
+LOAD_FLAG(PREFETCH, 1 << 21)
 
 // Indicates that this is a load that ignores limits and should complete
 // immediately.
-LOAD_FLAG(IGNORE_LIMITS, 1 << 23)
+LOAD_FLAG(IGNORE_LIMITS, 1 << 22)
 
 // Suppress login prompts for this request. Cached credentials or
 // default credentials may still be used for authentication.
-LOAD_FLAG(DO_NOT_PROMPT_FOR_LOGIN, 1 << 24)
+LOAD_FLAG(DO_NOT_PROMPT_FOR_LOGIN, 1 << 23)
 
 // Indicates that the operation is somewhat likely to be due to an
 // explicit user action. This can be used as a hint to treat the
 // request with higher priority.
-LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 25)
+LOAD_FLAG(MAYBE_USER_GESTURE, 1 << 24)
 
 // Indicates that the username:password portion of the URL should not
 // be honored, but that other forms of authority may be used.
-LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 26)
+LOAD_FLAG(DO_NOT_USE_EMBEDDED_IDENTITY, 1 << 25)
 
 // Send request directly to the origin if the effective proxy is the data
 // reduction proxy.
 // TODO(rcs): Remove this flag as soon as http://crbug.com/339237 is resolved.
-LOAD_FLAG(BYPASS_DATA_REDUCTION_PROXY, 1 << 27)
+LOAD_FLAG(BYPASS_DATA_REDUCTION_PROXY, 1 << 26)
 
 // Indicates the the request is an asynchronous revalidation.
-LOAD_FLAG(ASYNC_REVALIDATION, 1 << 28)
+LOAD_FLAG(ASYNC_REVALIDATION, 1 << 27)
diff --git a/net/base/net_info_source_list.h b/net/base/net_info_source_list.h
index be3019e..107840b 100644
--- a/net/base/net_info_source_list.h
+++ b/net/base/net_info_source_list.h
@@ -20,3 +20,4 @@
 NET_INFO_SOURCE(SPDY_ALT_PROTO_MAPPINGS, "spdyAlternateProtocolMappings",
                                                                          1 << 7)
 NET_INFO_SOURCE(HTTP_CACHE, "httpCacheInfo",                             1 << 8)
+NET_INFO_SOURCE(SDCH, "sdchInfo",                                        1 << 9)
diff --git a/net/base/net_log_event_type_list.h b/net/base/net_log_event_type_list.h
index 6dfe8c6..af7c290 100644
--- a/net/base/net_log_event_type_list.h
+++ b/net/base/net_log_event_type_list.h
@@ -2363,3 +2363,38 @@
 // This event is created (in a source of the same name) when the internal DNS
 // resolver creates a UDP socket to check for global IPv6 connectivity.
 EVENT_TYPE(IPV6_REACHABILITY_CHECK)
+
+// ------------------------------------------------------------------------
+// SDCH
+// ------------------------------------------------------------------------
+
+// This event is created when some problem occurs during sdch-encoded resource
+// handling. It contains the following parameters:
+//   {
+//     "sdch_problem_code": <SDCH problem code>,
+//     "net_error": <Always ERR_FAILED, present just to indicate this is a
+//                   failure>,
+//   }
+EVENT_TYPE(SDCH_DECODING_ERROR)
+
+// This event is created when SdchFilter initialization fails due to the
+// response corruption. It contains the following parameters:
+//   {
+//     "cause": <Response corruption detection cause>,
+//     "cached": <True if response was read from cache>,
+//   }
+EVENT_TYPE(SDCH_RESPONSE_CORRUPTION_DETECTION)
+
+// This event is created when some problem occurs during sdch dictionary fetch.
+// It contains the following parameters:
+//   {
+//     "dictionary_url": <Dictionary url>,
+//     "sdch_problem_code": <SDCH problem code>,
+//     "net_error": <Only present on unexpected errors. Always ERR_FAILED when
+//                   present. Used to indicate this is a real failure>,
+//   }
+EVENT_TYPE(SDCH_DICTIONARY_ERROR)
+
+// This event is created when SdchDictionaryFetcher starts fetch.  It contains
+// no parameters.
+EVENT_TYPE(SDCH_DICTIONARY_FETCH)
diff --git a/net/base/net_log_util.cc b/net/base/net_log_util.cc
index b8816ba..a15e899 100644
--- a/net/base/net_log_util.cc
+++ b/net/base/net_log_util.cc
@@ -15,6 +15,7 @@
 #include "net/base/load_states.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_log.h"
+#include "net/base/sdch_manager.h"
 #include "net/disk_cache/disk_cache.h"
 #include "net/dns/host_cache.h"
 #include "net/dns/host_resolver.h"
@@ -66,6 +67,14 @@
 #undef NET_ERROR
 };
 
+const StringToConstant kSdchProblems[] = {
+#define SDCH_PROBLEM_CODE(label, value) \
+  { #label, value }                     \
+  ,
+#include "net/base/sdch_problem_code_list.h"
+#undef SDCH_PROBLEM_CODE
+};
+
 const char* NetInfoSourceToString(NetInfoSource source) {
   switch (source) {
     #define NET_INFO_SOURCE(label, string, value) \
@@ -187,6 +196,17 @@
     constants_dict->Set("quicRstStreamError", dict);
   }
 
+  // Add information on the relationship between SDCH problem codes and their
+  // symbolic names.
+  {
+    base::DictionaryValue* dict = new base::DictionaryValue();
+
+    for (size_t i = 0; i < arraysize(kSdchProblems); i++)
+      dict->SetInteger(kSdchProblems[i].name, kSdchProblems[i].constant);
+
+    constants_dict->Set("sdchProblemCode", dict);
+  }
+
   // Information about the relationship between event phase enums and their
   // symbolic names.
   {
@@ -455,6 +475,17 @@
                        info_dict);
   }
 
+  if (info_sources & NET_INFO_SDCH) {
+    base::Value* info_dict;
+    SdchManager* sdch_manager = context->sdch_manager();
+    if (sdch_manager) {
+      info_dict = sdch_manager->SdchInfoToValue();
+    } else {
+      info_dict = new base::DictionaryValue();
+    }
+    net_info_dict->Set(NetInfoSourceToString(NET_INFO_SDCH), info_dict);
+  }
+
   return net_info_dict.Pass();
 }
 
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index b9cf59f..9dcf9df 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 #include <iterator>
+#include <limits>
 #include <set>
 
 #include "build/build_config.h"
@@ -294,6 +295,10 @@
   return StripWWW(base::ASCIIToUTF16(url.host()));
 }
 
+bool IsPortValid(int port) {
+  return port >= 0 && port <= std::numeric_limits<uint16>::max();
+}
+
 bool IsPortAllowedByDefault(int port) {
   int array_size = arraysize(kRestrictedPorts);
   for (int i = 0; i < array_size; i++) {
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 72ac169..44b913a 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -248,6 +248,10 @@
 // Runs |url|'s host through StripWWW().  |url| must be valid.
 NET_EXPORT base::string16 StripWWWFromHost(const GURL& url);
 
+// Checks if |port| is in the valid range (0 to 65535, though 0 is technically
+// reserved).  Should be used before casting a port to a uint16.
+NET_EXPORT bool IsPortValid(int port);
+
 // Checks |port| against a list of ports which are restricted by default.
 // Returns true if |port| is allowed, false if it is restricted.
 NET_EXPORT bool IsPortAllowedByDefault(int port);
diff --git a/net/base/net_util_linux.cc b/net/base/net_util_linux.cc
new file mode 100644
index 0000000..e4e0f7f
--- /dev/null
+++ b/net/base/net_util_linux.cc
@@ -0,0 +1,154 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/net_util_linux.h"
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <set>
+#include <sys/types.h>
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "net/base/address_tracker_linux.h"
+#include "net/base/escape.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_util_posix.h"
+#include "url/gurl.h"
+
+namespace net {
+
+namespace {
+
+// When returning true, the platform native IPv6 address attributes were
+// successfully converted to net IP address attributes. Otherwise, returning
+// false and the caller should drop the IP address which can't be used by the
+// application layer.
+bool TryConvertNativeToNetIPAttributes(int native_attributes,
+                                       int* net_attributes) {
+  // For Linux/ChromeOS/Android, we disallow addresses with attributes
+  // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
+  // are still progressing through duplicated address detection (DAD)
+  // and shouldn't be used by the application layer until DAD process
+  // is completed.
+  if (native_attributes & (
+#if !defined(OS_ANDROID)
+                              IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
+#endif  // !OS_ANDROID
+                              IFA_F_TENTATIVE)) {
+    return false;
+  }
+
+  if (native_attributes & IFA_F_TEMPORARY) {
+    *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
+  }
+
+  if (native_attributes & IFA_F_DEPRECATED) {
+    *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
+  }
+
+  return true;
+}
+
+}  // namespace
+
+namespace internal {
+
+inline const unsigned char* GetIPAddressData(const IPAddressNumber& ip) {
+#if defined(OS_ANDROID)
+  return ip.begin();
+#else
+  return ip.data();
+#endif
+}
+
+bool GetNetworkListImpl(
+    NetworkInterfaceList* networks,
+    int policy,
+    const base::hash_set<int>& online_links,
+    const internal::AddressTrackerLinux::AddressMap& address_map,
+    GetInterfaceNameFunction get_interface_name) {
+  std::map<int, std::string> ifnames;
+
+  for (internal::AddressTrackerLinux::AddressMap::const_iterator it =
+           address_map.begin();
+       it != address_map.end(); ++it) {
+    // Ignore addresses whose links are not online.
+    if (online_links.find(it->second.ifa_index) == online_links.end())
+      continue;
+
+    sockaddr_storage sock_addr;
+    socklen_t sock_len = sizeof(sockaddr_storage);
+
+    // Convert to sockaddr for next check.
+    if (!IPEndPoint(it->first, 0)
+             .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) {
+      continue;
+    }
+
+    // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
+    if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
+      continue;
+
+    int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
+
+    if (it->second.ifa_family == AF_INET6) {
+      // Ignore addresses whose attributes are not actionable by
+      // the application layer.
+      if (!TryConvertNativeToNetIPAttributes(it->second.ifa_flags,
+                                             &ip_attributes))
+        continue;
+    }
+
+    // Find the name of this link.
+    std::map<int, std::string>::const_iterator itname =
+        ifnames.find(it->second.ifa_index);
+    std::string ifname;
+    if (itname == ifnames.end()) {
+      char buffer[IF_NAMESIZE] = {0};
+      if (get_interface_name(it->second.ifa_index, buffer)) {
+        ifname = ifnames[it->second.ifa_index] = buffer;
+      } else {
+        // Ignore addresses whose interface name can't be retrieved.
+        continue;
+      }
+    } else {
+      ifname = itname->second;
+    }
+
+    // Based on the interface name and policy, determine whether we
+    // should ignore it.
+    if (ShouldIgnoreInterface(ifname, policy))
+      continue;
+
+    networks->push_back(
+        NetworkInterface(ifname, ifname, it->second.ifa_index,
+                         NetworkChangeNotifier::CONNECTION_UNKNOWN, it->first,
+                         it->second.ifa_prefixlen, ip_attributes));
+  }
+
+  return true;
+}
+
+}  // namespace internal
+
+bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
+  if (networks == NULL)
+    return false;
+
+  internal::AddressTrackerLinux tracker;
+  tracker.Init();
+
+  return internal::GetNetworkListImpl(networks, policy,
+                                      tracker.GetOnlineLinks(),
+                                      tracker.GetAddressMap(), &if_indextoname);
+}
+
+}  // namespace net
diff --git a/net/base/net_util_linux.h b/net/base/net_util_linux.h
new file mode 100644
index 0000000..340c380
--- /dev/null
+++ b/net/base/net_util_linux.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_NET_UTIL_LINUX_H_
+#define NET_BASE_NET_UTIL_LINUX_H_
+
+// This file is only used to expose some of the internals
+// of net_util_linux.cc to tests.
+
+#include "base/containers/hash_tables.h"
+#include "net/base/address_tracker_linux.h"
+#include "net/base/net_util.h"
+
+namespace net {
+namespace internal {
+
+typedef char* (*GetInterfaceNameFunction)(unsigned int interface_index,
+                                          char* ifname);
+
+NET_EXPORT bool GetNetworkListImpl(
+    NetworkInterfaceList* networks,
+    int policy,
+    const base::hash_set<int>& online_links,
+    const internal::AddressTrackerLinux::AddressMap& address_map,
+    GetInterfaceNameFunction get_interface_name);
+
+}  // namespace internal
+}  // namespace net
+
+#endif  // NET_BASE_NET_UTIL_LINUX_H_
diff --git a/net/base/net_util_mac.cc b/net/base/net_util_mac.cc
new file mode 100644
index 0000000..5dd4630
--- /dev/null
+++ b/net/base/net_util_mac.cc
@@ -0,0 +1,246 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/net_util_mac.h"
+
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <set>
+#include <sys/types.h>
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/strings/string_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "net/base/escape.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_util_posix.h"
+#include "url/gurl.h"
+
+#if !defined(OS_IOS)
+#include <net/if_media.h>
+#include <netinet/in_var.h>
+#include <sys/ioctl.h>
+#endif  // !OS_IOS
+
+namespace net {
+
+namespace {
+
+#if !defined(OS_IOS)
+
+// MacOSX implementation of IPAttributesGetterMac which calls ioctl on socket to
+// retrieve IP attributes.
+class IPAttributesGetterMacImpl : public internal::IPAttributesGetterMac {
+ public:
+  IPAttributesGetterMacImpl();
+  ~IPAttributesGetterMacImpl() override;
+  bool IsInitialized() const override;
+  bool GetIPAttributes(const char* ifname,
+                       const sockaddr* sock_addr,
+                       int* native_attributes) override;
+
+ private:
+  int ioctl_socket_;
+};
+
+IPAttributesGetterMacImpl::IPAttributesGetterMacImpl()
+    : ioctl_socket_(socket(AF_INET6, SOCK_DGRAM, 0)) {
+  DCHECK_GE(ioctl_socket_, 0);
+}
+
+bool IPAttributesGetterMacImpl::IsInitialized() const {
+  return ioctl_socket_ >= 0;
+}
+
+IPAttributesGetterMacImpl::~IPAttributesGetterMacImpl() {
+  if (ioctl_socket_ >= 0) {
+    close(ioctl_socket_);
+  }
+}
+
+bool IPAttributesGetterMacImpl::GetIPAttributes(const char* ifname,
+                                                const sockaddr* sock_addr,
+                                                int* native_attributes) {
+  struct in6_ifreq ifr = {};
+  strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1);
+  memcpy(&ifr.ifr_ifru.ifru_addr, sock_addr, sock_addr->sa_len);
+  int rv = ioctl(ioctl_socket_, SIOCGIFAFLAG_IN6, &ifr);
+  if (rv >= 0) {
+    *native_attributes = ifr.ifr_ifru.ifru_flags;
+  }
+  return (rv >= 0);
+}
+
+// When returning true, the platform native IPv6 address attributes were
+// successfully converted to net IP address attributes. Otherwise, returning
+// false and the caller should drop the IP address which can't be used by the
+// application layer.
+bool TryConvertNativeToNetIPAttributes(int native_attributes,
+                                       int* net_attributes) {
+  // For MacOSX, we disallow addresses with attributes IN6_IFF_ANYCASE,
+  // IN6_IFF_DUPLICATED, IN6_IFF_TENTATIVE, and IN6_IFF_DETACHED as these are
+  // still progressing through duplicated address detection (DAD) or are not
+  // suitable to be used in an one-to-one communication and shouldn't be used
+  // by the application layer.
+  if (native_attributes & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED |
+                           IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) {
+    return false;
+  }
+
+  if (native_attributes & IN6_IFF_TEMPORARY) {
+    *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
+  }
+
+  if (native_attributes & IN6_IFF_DEPRECATED) {
+    *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
+  }
+
+  return true;
+}
+
+NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
+    int addr_family,
+    const std::string& interface_name) {
+  NetworkChangeNotifier::ConnectionType type =
+      NetworkChangeNotifier::CONNECTION_UNKNOWN;
+
+  struct ifmediareq ifmr = {};
+  strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1);
+
+  int s = socket(addr_family, SOCK_DGRAM, 0);
+  if (s == -1) {
+    return type;
+  }
+
+  if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1) {
+    if (ifmr.ifm_current & IFM_IEEE80211) {
+      type = NetworkChangeNotifier::CONNECTION_WIFI;
+    } else if (ifmr.ifm_current & IFM_ETHER) {
+      type = NetworkChangeNotifier::CONNECTION_ETHERNET;
+    }
+  }
+  close(s);
+  return type;
+}
+
+#endif  // !OS_IOS
+}  // namespace
+
+namespace internal {
+
+bool GetNetworkListImpl(NetworkInterfaceList* networks,
+                        int policy,
+                        const ifaddrs* interfaces,
+                        IPAttributesGetterMac* ip_attributes_getter) {
+  // Enumerate the addresses assigned to network interfaces which are up.
+  for (const ifaddrs* interface = interfaces; interface != NULL;
+       interface = interface->ifa_next) {
+    // Skip loopback interfaces, and ones which are down.
+    if (!(IFF_RUNNING & interface->ifa_flags))
+      continue;
+    if (IFF_LOOPBACK & interface->ifa_flags)
+      continue;
+    // Skip interfaces with no address configured.
+    struct sockaddr* addr = interface->ifa_addr;
+    if (!addr)
+      continue;
+
+    // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
+    // configured on non-loopback interfaces.
+    if (IsLoopbackOrUnspecifiedAddress(addr))
+      continue;
+
+    const std::string& name = interface->ifa_name;
+    // Filter out VMware interfaces, typically named vmnet1 and vmnet8.
+    if (ShouldIgnoreInterface(name, policy)) {
+      continue;
+    }
+
+    NetworkChangeNotifier::ConnectionType connection_type =
+        NetworkChangeNotifier::CONNECTION_UNKNOWN;
+
+    int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
+
+#if !defined(OS_IOS)
+    // Retrieve native ip attributes and convert to net version if a getter is
+    // given.
+    if (ip_attributes_getter && ip_attributes_getter->IsInitialized()) {
+      int native_attributes = 0;
+      if (addr->sa_family == AF_INET6 &&
+          ip_attributes_getter->GetIPAttributes(
+              interface->ifa_name, interface->ifa_addr, &native_attributes)) {
+        if (!TryConvertNativeToNetIPAttributes(native_attributes,
+                                               &ip_attributes)) {
+          continue;
+        }
+      }
+    }
+
+    connection_type = GetNetworkInterfaceType(addr->sa_family, name);
+#endif  // !OS_IOS
+
+    IPEndPoint address;
+
+    int addr_size = 0;
+    if (addr->sa_family == AF_INET6) {
+      addr_size = sizeof(sockaddr_in6);
+    } else if (addr->sa_family == AF_INET) {
+      addr_size = sizeof(sockaddr_in);
+    }
+
+    if (address.FromSockAddr(addr, addr_size)) {
+      uint8 prefix_length = 0;
+      if (interface->ifa_netmask) {
+        // If not otherwise set, assume the same sa_family as ifa_addr.
+        if (interface->ifa_netmask->sa_family == 0) {
+          interface->ifa_netmask->sa_family = addr->sa_family;
+        }
+        IPEndPoint netmask;
+        if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) {
+          prefix_length = MaskPrefixLength(netmask.address());
+        }
+      }
+      networks->push_back(NetworkInterface(
+          name, name, if_nametoindex(name.c_str()), connection_type,
+          address.address(), prefix_length, ip_attributes));
+    }
+  }
+
+  return true;
+}
+
+}  // namespace internal
+
+bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
+  if (networks == NULL)
+    return false;
+
+  // getifaddrs() may require IO operations.
+  base::ThreadRestrictions::AssertIOAllowed();
+
+  ifaddrs* interfaces;
+  if (getifaddrs(&interfaces) < 0) {
+    PLOG(ERROR) << "getifaddrs";
+    return false;
+  }
+
+  scoped_ptr<internal::IPAttributesGetterMac> ip_attributes_getter;
+
+#if !defined(OS_IOS)
+  ip_attributes_getter.reset(new IPAttributesGetterMacImpl());
+#endif
+
+  bool result = internal::GetNetworkListImpl(networks, policy, interfaces,
+                                             ip_attributes_getter.get());
+  freeifaddrs(interfaces);
+  return result;
+}
+
+}  // namespace net
diff --git a/net/base/net_util_mac.h b/net/base/net_util_mac.h
new file mode 100644
index 0000000..178facc
--- /dev/null
+++ b/net/base/net_util_mac.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_NET_UTIL_MAC_H_
+#define NET_BASE_NET_UTIL_MAC_H_
+
+// This file is only used to expose some of the internals
+// of net_util_mac.cc to tests.
+
+#include "base/macros.h"
+#include "net/base/net_export.h"
+#include "net/base/net_util.h"
+
+struct ifaddrs;
+struct sockaddr;
+
+namespace net {
+namespace internal {
+
+class NET_EXPORT IPAttributesGetterMac {
+ public:
+  IPAttributesGetterMac() {}
+  virtual ~IPAttributesGetterMac() {}
+  virtual bool IsInitialized() const = 0;
+  virtual bool GetIPAttributes(const char* ifname,
+                               const sockaddr* sock_addr,
+                               int* native_attributes) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IPAttributesGetterMac);
+};
+
+NET_EXPORT bool GetNetworkListImpl(NetworkInterfaceList* networks,
+                                   int policy,
+                                   const ifaddrs* interfaces,
+                                   IPAttributesGetterMac* ip_attributes_getter);
+
+}  // namespace internal
+}  // namespace net
+
+#endif  // NET_BASE_NET_UTIL_MAC_H_
diff --git a/net/base/net_util_posix.cc b/net/base/net_util_posix.cc
index a2fa6cd..b8e7195 100644
--- a/net/base/net_util_posix.cc
+++ b/net/base/net_util_posix.cc
@@ -7,38 +7,18 @@
 #include <set>
 #include <sys/types.h>
 
-#include "base/files/file_path.h"
-#include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_tokenizer.h"
-#include "base/strings/string_util.h"
-#include "base/threading/thread_restrictions.h"
-#include "net/base/escape.h"
-#include "net/base/ip_endpoint.h"
-#include "net/base/net_errors.h"
-#include "url/gurl.h"
 
 #if !defined(OS_NACL)
-#if defined(OS_MACOSX)
-#include <ifaddrs.h>
-#else
-#include "net/base/address_tracker_linux.h"
 #include "net/base/net_util_posix.h"
-#endif  // OS_MACOSX
 #include <net/if.h>
 #include <netinet/in.h>
 #endif  // !defined(OS_NACL)
 
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-#include <net/if_media.h>
-#include <netinet/in_var.h>
-#include <sys/ioctl.h>
-#endif
-
 namespace net {
 
-namespace {
+#if !defined(OS_NACL)
+namespace internal {
 
 // The application layer can pass |policy| defined in net_util.h to
 // request filtering out certain type of interfaces.
@@ -77,330 +57,13 @@
   return false;
 }
 
-#if defined(OS_MACOSX)
-
-struct NetworkInterfaceInfo {
-  NetworkInterfaceInfo() : permanent(true) { }
-
-  bool permanent;  // IPv6 has notion of temporary address. If the address is
-                   // IPv6 and it's temporary this field will be false.
-  NetworkInterface interface;
-};
-
-// This method will remove permanent IPv6 addresses if a temporary address
-// is available for same network interface.
-void RemovePermanentIPv6AddressesWhereTemporaryExists(
-    std::vector<NetworkInterfaceInfo>* infos) {
-  if (!infos || infos->empty())
-    return;
-
-  // Build a set containing the names of interfaces with a temp IPv6 address
-  std::set<std::string> ifaces_with_temp_addrs;
-  std::vector<NetworkInterfaceInfo>::iterator i;
-  for (i = infos->begin(); i != infos->end(); ++i) {
-    if (!i->permanent && i->interface.address.size() == kIPv6AddressSize) {
-      ifaces_with_temp_addrs.insert(i->interface.name);
-    }
-  }
-
-  // If there are no such interfaces then there's no further work.
-  if (ifaces_with_temp_addrs.empty())
-    return;
-
-  // Search for permenent addresses belonging to same network interface.
-  for (i = infos->begin(); i != infos->end(); ) {
-    // If the address is IPv6 and it's permanent and there is temporary
-    // address for it, then we can remove this address.
-    if ((i->interface.address.size() == kIPv6AddressSize) && i->permanent &&
-        (ifaces_with_temp_addrs.find(i->interface.name) !=
-            ifaces_with_temp_addrs.end())) {
-      i = infos->erase(i);
-    } else {
-      ++i;
-    }
-  }
-}
-
-#if !defined(OS_IOS)
-NetworkChangeNotifier::ConnectionType GetNetworkInterfaceType(
-    int addr_family, const std::string& interface_name) {
-  NetworkChangeNotifier::ConnectionType type =
-      NetworkChangeNotifier::CONNECTION_UNKNOWN;
-
-  struct ifmediareq ifmr = {};
-  strncpy(ifmr.ifm_name, interface_name.c_str(), sizeof(ifmr.ifm_name) - 1);
-
-  int s = socket(addr_family, SOCK_DGRAM, 0);
-  if (s == -1) {
-    return type;
-  }
-
-  if (ioctl(s, SIOCGIFMEDIA, &ifmr) != -1) {
-    if (ifmr.ifm_current & IFM_IEEE80211) {
-      type = NetworkChangeNotifier::CONNECTION_WIFI;
-    } else if (ifmr.ifm_current & IFM_ETHER) {
-      type = NetworkChangeNotifier::CONNECTION_ETHERNET;
-    }
-  }
-  close(s);
-  return type;
-}
-
-#endif                   // !defined(OS_IOS)
-#elif !defined(OS_NACL)  // OS_MACOSX
-
-// Convert platform native IPv6 address attributes to net IP address
-// attributes and drop ones that can't be used by the application
-// layer.
-bool TryConvertNativeToNetIPAttributes(int native_attributes,
-                                       int* net_attributes) {
-  // For Linux/ChromeOS/Android, we disallow addresses with attributes
-  // IFA_F_OPTIMISTIC, IFA_F_DADFAILED, and IFA_F_TENTATIVE as these
-  // are still progressing through duplicated address detection (DAD)
-  // and shouldn't be used by the application layer until DAD process
-  // is completed.
-  if (native_attributes & (
-#if !defined(OS_ANDROID)
-    IFA_F_OPTIMISTIC | IFA_F_DADFAILED |
-#endif  // !OS_ANDROID
-    IFA_F_TENTATIVE)) {
-    return false;
-  }
-
-  if (native_attributes & IFA_F_TEMPORARY) {
-    *net_attributes |= IP_ADDRESS_ATTRIBUTE_TEMPORARY;
-  }
-
-  if (native_attributes & IFA_F_DEPRECATED) {
-    *net_attributes |= IP_ADDRESS_ATTRIBUTE_DEPRECATED;
-  }
-
-  return true;
-}
-#endif  // OS_MACOSX
-}  // namespace
-
-namespace internal {
-
-#if !defined(OS_MACOSX) && !defined(OS_NACL)
-
-inline const unsigned char* GetIPAddressData(const IPAddressNumber& ip) {
-#if defined(OS_ANDROID)
-  return ip.begin();
-#else
-  return ip.data();
-#endif
-}
-
-bool GetNetworkListImpl(
-    NetworkInterfaceList* networks,
-    int policy,
-    const base::hash_set<int>& online_links,
-    const internal::AddressTrackerLinux::AddressMap& address_map,
-    GetInterfaceNameFunction get_interface_name) {
-  std::map<int, std::string> ifnames;
-
-  for (internal::AddressTrackerLinux::AddressMap::const_iterator it =
-           address_map.begin();
-       it != address_map.end();
-       ++it) {
-    // Ignore addresses whose links are not online.
-    if (online_links.find(it->second.ifa_index) == online_links.end())
-      continue;
-
-    sockaddr_storage sock_addr;
-    socklen_t sock_len = sizeof(sockaddr_storage);
-
-    // Convert to sockaddr for next check.
-    if (!IPEndPoint(it->first, 0)
-             .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addr), &sock_len)) {
-      continue;
-    }
-
-    // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
-    if (IsLoopbackOrUnspecifiedAddress(reinterpret_cast<sockaddr*>(&sock_addr)))
-      continue;
-
-    int ip_attributes = IP_ADDRESS_ATTRIBUTE_NONE;
-
-    if (it->second.ifa_family == AF_INET6) {
-      // Ignore addresses whose attributes are not actionable by
-      // the application layer.
-      if (!TryConvertNativeToNetIPAttributes(it->second.ifa_flags,
-                                             &ip_attributes))
-        continue;
-    }
-
-    // Find the name of this link.
-    std::map<int, std::string>::const_iterator itname =
-        ifnames.find(it->second.ifa_index);
-    std::string ifname;
-    if (itname == ifnames.end()) {
-      char buffer[IF_NAMESIZE] = {0};
-      if (get_interface_name(it->second.ifa_index, buffer)) {
-        ifname = ifnames[it->second.ifa_index] = buffer;
-      } else {
-        // Ignore addresses whose interface name can't be retrieved.
-        continue;
-      }
-    } else {
-      ifname = itname->second;
-    }
-
-    // Based on the interface name and policy, determine whether we
-    // should ignore it.
-    if (ShouldIgnoreInterface(ifname, policy))
-      continue;
-
-    networks->push_back(
-        NetworkInterface(ifname,
-                         ifname,
-                         it->second.ifa_index,
-                         NetworkChangeNotifier::CONNECTION_UNKNOWN,
-                         it->first,
-                         it->second.ifa_prefixlen,
-                         ip_attributes));
-  }
-
-  return true;
-}
-#endif
-
 }  // namespace internal
-
+#else   // OS_NACL
 bool GetNetworkList(NetworkInterfaceList* networks, int policy) {
-  if (networks == NULL)
-    return false;
-#if defined(OS_NACL)
   NOTIMPLEMENTED();
   return false;
-#elif !defined(OS_MACOSX)
-
-  internal::AddressTrackerLinux tracker;
-  tracker.Init();
-
-  return internal::GetNetworkListImpl(networks,
-                                      policy,
-                                      tracker.GetOnlineLinks(),
-                                      tracker.GetAddressMap(),
-                                      &if_indextoname);
-
-#else  // Only OS_MACOSX and OS_IOS will run the code below
-
-  // getifaddrs() may require IO operations.
-  base::ThreadRestrictions::AssertIOAllowed();
-
-#if !defined(OS_IOS)
-  int ioctl_socket = -1;
-  if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
-    // we need a socket to query information about temporary address.
-    ioctl_socket = socket(AF_INET6, SOCK_DGRAM, 0);
-    DCHECK_GT(ioctl_socket, 0);
-  }
-#endif
-
-  ifaddrs* interfaces;
-  if (getifaddrs(&interfaces) < 0) {
-    PLOG(ERROR) << "getifaddrs";
-    return false;
-  }
-
-  std::vector<NetworkInterfaceInfo> network_infos;
-
-  // Enumerate the addresses assigned to network interfaces which are up.
-  for (ifaddrs *interface = interfaces;
-       interface != NULL;
-       interface = interface->ifa_next) {
-    // Skip loopback interfaces, and ones which are down.
-    if (!(IFF_UP & interface->ifa_flags))
-      continue;
-    if (IFF_LOOPBACK & interface->ifa_flags)
-      continue;
-    // Skip interfaces with no address configured.
-    struct sockaddr* addr = interface->ifa_addr;
-    if (!addr)
-      continue;
-
-    // Skip unspecified addresses (i.e. made of zeroes) and loopback addresses
-    // configured on non-loopback interfaces.
-    if (IsLoopbackOrUnspecifiedAddress(addr))
-      continue;
-
-    int addr_size = 0;
-    if (addr->sa_family == AF_INET6) {
-      addr_size = sizeof(sockaddr_in6);
-    } else if (addr->sa_family == AF_INET) {
-      addr_size = sizeof(sockaddr_in);
-    }
-
-    const std::string& name = interface->ifa_name;
-    // Filter out VMware interfaces, typically named vmnet1 and vmnet8.
-    if (ShouldIgnoreInterface(name, policy)) {
-      continue;
-    }
-
-    NetworkInterfaceInfo network_info;
-    NetworkChangeNotifier::ConnectionType connection_type =
-        NetworkChangeNotifier::CONNECTION_UNKNOWN;
-#if !defined(OS_IOS)
-    // Check if this is a temporary address. Currently this is only supported
-    // on Mac.
-    if ((policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) &&
-        ioctl_socket >= 0 && addr->sa_family == AF_INET6) {
-      struct in6_ifreq ifr = {};
-      strncpy(ifr.ifr_name, interface->ifa_name, sizeof(ifr.ifr_name) - 1);
-      memcpy(&ifr.ifr_ifru.ifru_addr, interface->ifa_addr,
-             interface->ifa_addr->sa_len);
-      int rv = ioctl(ioctl_socket, SIOCGIFAFLAG_IN6, &ifr);
-      if (rv >= 0) {
-        network_info.permanent = !(ifr.ifr_ifru.ifru_flags & IN6_IFF_TEMPORARY);
-      }
-    }
-
-    connection_type = GetNetworkInterfaceType(addr->sa_family, name);
-#endif
-
-    IPEndPoint address;
-    if (address.FromSockAddr(addr, addr_size)) {
-      uint8 net_mask = 0;
-      if (interface->ifa_netmask) {
-        // If not otherwise set, assume the same sa_family as ifa_addr.
-        if (interface->ifa_netmask->sa_family == 0) {
-          interface->ifa_netmask->sa_family = addr->sa_family;
-        }
-        IPEndPoint netmask;
-        if (netmask.FromSockAddr(interface->ifa_netmask, addr_size)) {
-          net_mask = MaskPrefixLength(netmask.address());
-        }
-      }
-      network_info.interface = NetworkInterface(name,
-                                                name,
-                                                if_nametoindex(name.c_str()),
-                                                connection_type,
-                                                address.address(),
-                                                net_mask,
-                                                IP_ADDRESS_ATTRIBUTE_NONE);
-
-      network_infos.push_back(NetworkInterfaceInfo(network_info));
-    }
-  }
-  freeifaddrs(interfaces);
-#if !defined(OS_IOS)
-  if (ioctl_socket >= 0) {
-    close(ioctl_socket);
-  }
-#endif
-
-  if (policy & INCLUDE_ONLY_TEMP_IPV6_ADDRESS_IF_POSSIBLE) {
-    RemovePermanentIPv6AddressesWhereTemporaryExists(&network_infos);
-  }
-
-  for (size_t i = 0; i < network_infos.size(); ++i) {
-    networks->push_back(network_infos[i].interface);
-  }
-  return true;
-#endif
 }
+#endif  // OS_NACL
 
 WifiPHYLayerProtocol GetWifiPHYLayerProtocol() {
   return WIFI_PHY_LAYER_PROTOCOL_UNKNOWN;
diff --git a/net/base/net_util_posix.h b/net/base/net_util_posix.h
index b553d1c..93089c2 100644
--- a/net/base/net_util_posix.h
+++ b/net/base/net_util_posix.h
@@ -5,27 +5,21 @@
 #ifndef NET_BASE_NET_UTIL_POSIX_H_
 #define NET_BASE_NET_UTIL_POSIX_H_
 
-// This file is only used to expose some of the internals
-// of net_util_posix.cc to tests.
+// This file is only used to expose some of the internals of
+// net_util_posix.cc to net_util_linux.cc and net_util_mac.cc.
+
+#include <string>
+
+struct sockaddr;
 
 namespace net {
 namespace internal {
-
-#if !defined(OS_MACOSX) && !defined(OS_NACL)
-typedef char* (*GetInterfaceNameFunction)(unsigned int interface_index,
-                                          char* ifname);
-
-NET_EXPORT bool GetNetworkListImpl(
-    NetworkInterfaceList* networks,
-    int policy,
-    const base::hash_set<int>& online_links,
-    const internal::AddressTrackerLinux::AddressMap& address_map,
-    GetInterfaceNameFunction get_interface_name);
-
-#endif  // !OS_MACOSX && !OS_NACL
+#if !defined(OS_NACL)
+bool ShouldIgnoreInterface(const std::string& name, int policy);
+bool IsLoopbackOrUnspecifiedAddress(const sockaddr* addr);
+#endif  // !OS_NACL
 
 }  // namespace internal
-
 }  // namespace net
 
 #endif  // NET_BASE_NET_UTIL_POSIX_H_
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 45f0857..a25903a 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -17,10 +17,17 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/sys_byteorder.h"
 #include "base/time/time.h"
+#include "net/base/ip_endpoint.h"
 
 #if !defined(OS_NACL) && !defined(OS_WIN)
 #include <net/if.h>
 #include <netinet/in.h>
+#if defined(OS_MACOSX)
+#include <ifaddrs.h>
+#if !defined(OS_IOS)
+#include <netinet/in_var.h>
+#endif  // !OS_IOS
+#endif  // OS_MACOSX
 #endif  // !OS_NACL && !OS_WIN
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -38,6 +45,11 @@
 
 #if !defined(OS_WIN)
 #include "net/base/net_util_posix.h"
+#if defined(OS_MACOSX)
+#include "net/base/net_util_mac.h"
+#else  // OS_MACOSX
+#include "net/base/net_util_linux.h"
+#endif
 #endif  // !OS_WIN
 
 using base::ASCIIToUTF16;
@@ -85,6 +97,58 @@
   return out;
 }
 
+#if defined(OS_MACOSX)
+class IPAttributesGetterTest : public internal::IPAttributesGetterMac {
+ public:
+  IPAttributesGetterTest() : native_attributes_(0) {}
+  bool IsInitialized() const override { return true; }
+  bool GetIPAttributes(const char* ifname,
+                       const sockaddr* sock_addr,
+                       int* native_attributes) override {
+    *native_attributes = native_attributes_;
+    return true;
+  }
+  void set_native_attributes(int native_attributes) {
+    native_attributes_ = native_attributes;
+  }
+
+ private:
+  int native_attributes_;
+};
+
+// Helper function to create a single valid ifaddrs
+bool FillIfaddrs(ifaddrs* interfaces,
+                 const char* ifname,
+                 uint flags,
+                 const IPAddressNumber& ip_address,
+                 const IPAddressNumber& ip_netmask,
+                 sockaddr_storage sock_addrs[2]) {
+  interfaces->ifa_next = NULL;
+  interfaces->ifa_name = const_cast<char*>(ifname);
+  interfaces->ifa_flags = flags;
+
+  socklen_t sock_len = sizeof(sockaddr_storage);
+
+  // Convert to sockaddr for next check.
+  if (!IPEndPoint(ip_address, 0)
+           .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[0]),
+                       &sock_len)) {
+    return false;
+  }
+  interfaces->ifa_addr = reinterpret_cast<sockaddr*>(&sock_addrs[0]);
+
+  sock_len = sizeof(sockaddr_storage);
+  if (!IPEndPoint(ip_netmask, 0)
+           .ToSockAddr(reinterpret_cast<sockaddr*>(&sock_addrs[1]),
+                       &sock_len)) {
+    return false;
+  }
+  interfaces->ifa_netmask = reinterpret_cast<sockaddr*>(&sock_addrs[1]);
+
+  return true;
+}
+#endif  // OS_MACOSX
+
 }  // anonymous namespace
 
 TEST(NetUtilTest, GetIdentityFromURL) {
@@ -812,6 +876,18 @@
   }
 }
 
+static const char ifname_em1[] = "em1";
+static const char ifname_vm[] = "vmnet";
+
+static const unsigned char kIPv6LocalAddr[] = {
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+static const unsigned char kIPv6Addr[] =
+  {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
+   0xfe, 0xe5, 0x00, 0xc3};
+static const unsigned char kIPv6Netmask[] =
+  {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00};
+
 #if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_NACL)
 
 char* CopyInterfaceName(const char* ifname, int ifname_size, char* output) {
@@ -820,30 +896,24 @@
   return output;
 }
 
-static const char ifname_em1[] = "em1";
 char* GetInterfaceName(unsigned int interface_index, char* ifname) {
   return CopyInterfaceName(ifname_em1, arraysize(ifname_em1), ifname);
 }
 
-static const char ifname_vm[] = "vmnet";
 char* GetInterfaceNameVM(unsigned int interface_index, char* ifname) {
   return CopyInterfaceName(ifname_vm, arraysize(ifname_vm), ifname);
 }
 
 TEST(NetUtilTest, GetNetworkListTrimming) {
-  NetworkInterfaceList results;
-  ::base::hash_set<int> online_links;
-  net::internal::AddressTrackerLinux::AddressMap address_map;
-
-  const unsigned char kIPv6LocalAddr[] = {
-      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
-  const unsigned char kIPv6Addr[] =
-    {0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
-     0xfe, 0xe5, 0x00, 0xc3};
-
   IPAddressNumber ipv6_local_address(
       kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
   IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
+  IPAddressNumber ipv6_netmask(kIPv6Netmask,
+                               kIPv6Netmask + arraysize(kIPv6Netmask));
+
+  NetworkInterfaceList results;
+  ::base::hash_set<int> online_links;
+  net::internal::AddressTrackerLinux::AddressMap address_map;
 
   // Interface 1 is offline.
   struct ifaddrmsg msg = {
@@ -956,7 +1026,101 @@
   results.clear();
 }
 
-#endif
+#elif defined(OS_MACOSX)
+
+TEST(NetUtilTest, GetNetworkListTrimming) {
+  IPAddressNumber ipv6_local_address(
+      kIPv6LocalAddr, kIPv6LocalAddr + arraysize(kIPv6LocalAddr));
+  IPAddressNumber ipv6_address(kIPv6Addr, kIPv6Addr + arraysize(kIPv6Addr));
+  IPAddressNumber ipv6_netmask(kIPv6Netmask,
+                               kIPv6Netmask + arraysize(kIPv6Netmask));
+
+  NetworkInterfaceList results;
+  IPAttributesGetterTest ip_attributes_getter;
+  sockaddr_storage addresses[2];
+  ifaddrs interface;
+
+  // Address of offline links should be ignored.
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_UP, ipv6_address,
+                          ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 0ul);
+
+  // Local address should be trimmed out.
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING,
+                          ipv6_local_address, ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 0ul);
+
+  // vmware address should return by default.
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_vm, IFF_RUNNING, ipv6_address,
+                          ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 1ul);
+  EXPECT_EQ(results[0].name, ifname_vm);
+  EXPECT_EQ(results[0].network_prefix, 1ul);
+  EXPECT_EQ(results[0].address, ipv6_address);
+  results.clear();
+
+  // vmware address should be trimmed out if policy specified so.
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_vm, IFF_RUNNING, ipv6_address,
+                          ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 0ul);
+  results.clear();
+
+#if !defined(OS_IOS)
+  // Addresses with banned attributes should be ignored.
+  ip_attributes_getter.set_native_attributes(IN6_IFF_ANYCAST);
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING, ipv6_address,
+                          ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 0ul);
+  results.clear();
+
+  // Addresses with allowed attribute IFA_F_TEMPORARY should be returned and
+  // attributes should be translated correctly.
+  ip_attributes_getter.set_native_attributes(IN6_IFF_TEMPORARY);
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING, ipv6_address,
+                          ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 1ul);
+  EXPECT_EQ(results[0].name, ifname_em1);
+  EXPECT_EQ(results[0].network_prefix, 1ul);
+  EXPECT_EQ(results[0].address, ipv6_address);
+  EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_TEMPORARY);
+  results.clear();
+
+  // Addresses with allowed attribute IFA_F_DEPRECATED should be returned and
+  // attributes should be translated correctly.
+  ip_attributes_getter.set_native_attributes(IN6_IFF_DEPRECATED);
+  ASSERT_TRUE(FillIfaddrs(&interface, ifname_em1, IFF_RUNNING, ipv6_address,
+                          ipv6_netmask, addresses));
+  EXPECT_TRUE(net::internal::GetNetworkListImpl(
+      &results, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES, &interface,
+      &ip_attributes_getter));
+  EXPECT_EQ(results.size(), 1ul);
+  EXPECT_EQ(results[0].name, ifname_em1);
+  EXPECT_EQ(results[0].network_prefix, 1ul);
+  EXPECT_EQ(results[0].address, ipv6_address);
+  EXPECT_EQ(results[0].ip_address_attributes, IP_ADDRESS_ATTRIBUTE_DEPRECATED);
+  results.clear();
+#endif  // !OS_IOS
+}
+
+#endif  // !OS_MACOSX && !OS_WIN && !OS_NACL
 
 namespace {
 
diff --git a/net/base/network_activity_monitor.cc b/net/base/network_activity_monitor.cc
new file mode 100644
index 0000000..78da8c8
--- /dev/null
+++ b/net/base/network_activity_monitor.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/network_activity_monitor.h"
+
+namespace net {
+
+namespace {
+
+base::LazyInstance<NetworkActivityMonitor>::Leaky g_network_activity_monitor =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+NetworkActivityMonitor::NetworkActivityMonitor()
+    : bytes_received_(0), bytes_sent_(0) {
+}
+
+NetworkActivityMonitor::~NetworkActivityMonitor() {
+}
+
+// static
+NetworkActivityMonitor* NetworkActivityMonitor::GetInstance() {
+  return g_network_activity_monitor.Pointer();
+}
+
+void NetworkActivityMonitor::IncrementBytesReceived(uint64_t bytes_received) {
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::AutoLock lock(lock_);
+  bytes_received_ += bytes_received;
+  last_received_ticks_ = now;
+}
+
+void NetworkActivityMonitor::IncrementBytesSent(uint64_t bytes_sent) {
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::AutoLock lock(lock_);
+  bytes_sent_ += bytes_sent;
+  last_sent_ticks_ = now;
+}
+
+uint64_t NetworkActivityMonitor::GetBytesReceived() const {
+  base::AutoLock lock(lock_);
+  return bytes_received_;
+}
+
+uint64_t NetworkActivityMonitor::GetBytesSent() const {
+  base::AutoLock lock(lock_);
+  return bytes_sent_;
+}
+
+base::TimeDelta NetworkActivityMonitor::GetTimeSinceLastReceived() const {
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::AutoLock lock(lock_);
+  return now - last_received_ticks_;
+}
+
+base::TimeDelta NetworkActivityMonitor::GetTimeSinceLastSent() const {
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::AutoLock lock(lock_);
+  return now - last_sent_ticks_;
+}
+
+}  // namespace net
diff --git a/net/base/network_activity_monitor.h b/net/base/network_activity_monitor.h
new file mode 100644
index 0000000..5319477
--- /dev/null
+++ b/net/base/network_activity_monitor.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_NETWORK_ACTIVITY_MONITOR_H_
+#define NET_BASE_NETWORK_ACTIVITY_MONITOR_H_
+
+#include "base/basictypes.h"
+#include "base/lazy_instance.h"
+#include "base/synchronization/lock.h"
+#include "base/time/time.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+namespace test {
+
+class NetworkActivityMonitorPeer;
+
+}  // namespace test
+
+// NetworkActivityMonitor tracks network activity across all sockets and
+// provides cumulative statistics about bytes sent to and received from
+// the network. It uses a lock to ensure thread-safety.
+//
+// There are a few caveats:
+//  * Bytes "sent" includes all send attempts and may include
+//    some bytes which were actually never sent over the network.
+//  * Bytes received includes only bytes actually received from the network,
+//    and does not include any bytes read from the the cache.
+//  * Network activity not initiated directly using chromium sockets won't
+//    be reflected here (for instance DNS queries issued by getaddrinfo()).
+class NET_EXPORT_PRIVATE NetworkActivityMonitor {
+ public:
+  // Returns the singleton instance of the monitor.
+  static NetworkActivityMonitor* GetInstance();
+
+  void IncrementBytesReceived(uint64_t bytes_received);
+  void IncrementBytesSent(uint64_t bytes_sent);
+
+  uint64_t GetBytesReceived() const;
+  uint64_t GetBytesSent() const;
+
+  base::TimeDelta GetTimeSinceLastReceived() const;
+  base::TimeDelta GetTimeSinceLastSent() const;
+
+ private:
+  friend class test::NetworkActivityMonitorPeer;
+
+  NetworkActivityMonitor();
+  ~NetworkActivityMonitor();
+  friend struct base::DefaultLazyInstanceTraits<NetworkActivityMonitor>;
+
+  // Protects all the following members.
+  mutable base::Lock lock_;
+
+  uint64_t bytes_received_;
+  uint64_t bytes_sent_;
+
+  base::TimeTicks last_received_ticks_;
+  base::TimeTicks last_sent_ticks_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkActivityMonitor);
+};
+
+}  // namespace net
+
+#endif  // NET_BASE_NETWORK_ACTIVITY_MONITOR_H_
diff --git a/net/base/network_activity_monitor_unittest.cc b/net/base/network_activity_monitor_unittest.cc
new file mode 100644
index 0000000..e625c55
--- /dev/null
+++ b/net/base/network_activity_monitor_unittest.cc
@@ -0,0 +1,131 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/network_activity_monitor.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/port.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace test {
+
+class NetworkActivityMonitorPeer {
+ public:
+  static void ResetMonitor() {
+    NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
+    base::AutoLock lock(monitor->lock_);
+    monitor->bytes_sent_ = 0;
+    monitor->bytes_received_ = 0;
+    monitor->last_received_ticks_ = base::TimeTicks();
+    monitor->last_sent_ticks_ = base::TimeTicks();
+  }
+};
+
+
+class NetworkActivityMontiorTest : public testing::Test {
+ public:
+  NetworkActivityMontiorTest() {
+    NetworkActivityMonitorPeer::ResetMonitor();
+  }
+};
+
+TEST_F(NetworkActivityMontiorTest, GetInstance) {
+  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
+  EXPECT_TRUE(monitor != NULL);
+  EXPECT_TRUE(monitor == NetworkActivityMonitor::GetInstance());
+}
+
+TEST_F(NetworkActivityMontiorTest, BytesReceived) {
+  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
+
+  EXPECT_EQ(0u, monitor->GetBytesReceived());
+
+  base::TimeTicks start = base::TimeTicks::Now();
+  uint64_t bytes = 12345;
+  monitor->IncrementBytesReceived(bytes);
+  EXPECT_EQ(bytes, monitor->GetBytesReceived());
+  base::TimeDelta delta = monitor->GetTimeSinceLastReceived();
+  EXPECT_LE(base::TimeDelta(), delta);
+  EXPECT_GE(base::TimeTicks::Now() - start, delta);
+}
+
+TEST_F(NetworkActivityMontiorTest, BytesSent) {
+  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
+
+  EXPECT_EQ(0u, monitor->GetBytesSent());
+
+  base::TimeTicks start = base::TimeTicks::Now();
+  uint64_t bytes = 12345;
+  monitor->IncrementBytesSent(bytes);
+  EXPECT_EQ(bytes, monitor->GetBytesSent());
+  base::TimeDelta delta = monitor->GetTimeSinceLastSent();
+  EXPECT_LE(base::TimeDelta(), delta);
+  EXPECT_GE(base::TimeTicks::Now() - start, delta);
+}
+
+namespace {
+
+void VerifyBytesReceivedIsMultipleOf(uint64_t bytes) {
+  EXPECT_EQ(0u,
+            NetworkActivityMonitor::GetInstance()->GetBytesReceived() % bytes);
+}
+
+void VerifyBytesSentIsMultipleOf(uint64_t bytes) {
+  EXPECT_EQ(0u, NetworkActivityMonitor::GetInstance()->GetBytesSent() % bytes);
+}
+
+void IncrementBytesReceived(uint64_t bytes) {
+  NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(bytes);
+}
+
+void IncrementBytesSent(uint64_t bytes) {
+  NetworkActivityMonitor::GetInstance()->IncrementBytesSent(bytes);
+}
+
+}  // namespace
+
+TEST_F(NetworkActivityMontiorTest, Threading) {
+  std::vector<base::Thread*> threads;
+  for (size_t i = 0; i < 3; ++i) {
+    threads.push_back(new base::Thread(base::UintToString(i)));
+    ASSERT_TRUE(threads.back()->Start());
+  }
+
+  size_t num_increments = 157;
+  uint64_t bytes_received = GG_UINT64_C(7294954321);
+  uint64_t bytes_sent = GG_UINT64_C(91294998765);
+  for (size_t i = 0; i < num_increments; ++i) {
+    size_t thread_num = i % threads.size();
+    threads[thread_num]->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&IncrementBytesReceived, bytes_received));
+    threads[thread_num]->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&IncrementBytesSent, bytes_sent));
+    threads[thread_num]->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&VerifyBytesSentIsMultipleOf, bytes_sent));
+    threads[thread_num]->task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&VerifyBytesReceivedIsMultipleOf, bytes_received));
+  }
+
+  STLDeleteElements(&threads);
+
+  NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance();
+  EXPECT_EQ(num_increments * bytes_received, monitor->GetBytesReceived());
+  EXPECT_EQ(num_increments * bytes_sent, monitor->GetBytesSent());
+}
+
+}  // namespace test
+
+}  // namespace net
diff --git a/net/base/sdch_manager.cc b/net/base/sdch_manager.cc
index 1285ad9..af5e6ee 100644
--- a/net/base/sdch_manager.cc
+++ b/net/base/sdch_manager.cc
@@ -9,6 +9,7 @@
 #include "base/metrics/histogram.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
+#include "base/values.h"
 #include "crypto/sha2.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "net/base/sdch_observer.h"
@@ -78,7 +79,8 @@
 SdchManager::Dictionary::~Dictionary() {
 }
 
-bool SdchManager::Dictionary::CanAdvertise(const GURL& target_url) {
+SdchProblemCode SdchManager::Dictionary::CanAdvertise(
+    const GURL& target_url) const {
   /* The specific rules of when a dictionary should be advertised in an
      Avail-Dictionary header are modeled after the rules for cookie scoping. The
      terms "domain-match" and "pathmatch" are defined in RFC 2965 [6]. A
@@ -95,28 +97,28 @@
      url scheme.
     */
   if (!DomainMatch(target_url, domain_))
-    return false;
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
   if (!ports_.empty() && 0 == ports_.count(target_url.EffectiveIntPort()))
-    return false;
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
   if (path_.size() && !PathMatch(target_url.path(), path_))
-    return false;
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
   if (!SdchManager::secure_scheme_supported() && target_url.SchemeIsSecure())
-    return false;
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
   if (target_url.SchemeIsSecure() != url_.SchemeIsSecure())
-    return false;
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
   if (base::Time::Now() > expiration_)
-    return false;
-  return true;
+    return SDCH_DICTIONARY_FOUND_EXPIRED;
+  return SDCH_OK;
 }
 
 //------------------------------------------------------------------------------
 // Security functions restricting loads and use of dictionaries.
 
 // static
-bool SdchManager::Dictionary::CanSet(const std::string& domain,
-                                     const std::string& path,
-                                     const std::set<int>& ports,
-                                     const GURL& dictionary_url) {
+SdchProblemCode SdchManager::Dictionary::CanSet(const std::string& domain,
+                                                const std::string& path,
+                                                const std::set<int>& ports,
+                                                const GURL& dictionary_url) {
   /*
   A dictionary is invalid and must not be stored if any of the following are
   true:
@@ -135,20 +137,17 @@
   // and hence the conservative approach is to not allow any redirects (if there
   // were any... then don't allow the dictionary to be set).
 
-  if (domain.empty()) {
-    SdchErrorRecovery(DICTIONARY_MISSING_DOMAIN_SPECIFIER);
-    return false;  // Domain is required.
-  }
+  if (domain.empty())
+    return SDCH_DICTIONARY_MISSING_DOMAIN_SPECIFIER;  // Domain is required.
+
   if (registry_controlled_domains::GetDomainAndRegistry(
-        domain,
-        registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES).empty()) {
-    SdchErrorRecovery(DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN);
-    return false;  // domain was a TLD.
+          domain, registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)
+          .empty()) {
+    return SDCH_DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN;  // domain was a TLD.
   }
-  if (!Dictionary::DomainMatch(dictionary_url, domain)) {
-    SdchErrorRecovery(DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL);
-    return false;
-  }
+
+  if (!Dictionary::DomainMatch(dictionary_url, domain))
+    return SDCH_DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL;
 
   std::string referrer_url_host = dictionary_url.host();
   size_t postfix_domain_index = referrer_url_host.rfind(domain);
@@ -156,23 +155,20 @@
   if (referrer_url_host.size() == postfix_domain_index + domain.size()) {
     // It is a postfix... so check to see if there's a dot in the prefix.
     size_t end_of_host_index = referrer_url_host.find_first_of('.');
-    if (referrer_url_host.npos != end_of_host_index  &&
+    if (referrer_url_host.npos != end_of_host_index &&
         end_of_host_index < postfix_domain_index) {
-      SdchErrorRecovery(DICTIONARY_REFERER_URL_HAS_DOT_IN_PREFIX);
-      return false;
+      return SDCH_DICTIONARY_REFERER_URL_HAS_DOT_IN_PREFIX;
     }
   }
 
-  if (!ports.empty()
-      && 0 == ports.count(dictionary_url.EffectiveIntPort())) {
-    SdchErrorRecovery(DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL);
-    return false;
-  }
-  return true;
+  if (!ports.empty() && 0 == ports.count(dictionary_url.EffectiveIntPort()))
+    return SDCH_DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL;
+
+  return SDCH_OK;
 }
 
-// static
-bool SdchManager::Dictionary::CanUse(const GURL& referring_url) {
+SdchProblemCode SdchManager::Dictionary::CanUse(
+    const GURL& referring_url) const {
   /*
     1. The request URL's host name domain-matches the Domain attribute of the
       dictionary.
@@ -184,39 +180,30 @@
     HTTPS support AND the dictionary acquisition scheme matches the target
      url scheme.
   */
-  if (!DomainMatch(referring_url, domain_)) {
-    SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_DOMAIN);
-    return false;
-  }
-  if (!ports_.empty()
-      && 0 == ports_.count(referring_url.EffectiveIntPort())) {
-    SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_PORT_LIST);
-    return false;
-  }
-  if (path_.size() && !PathMatch(referring_url.path(), path_)) {
-    SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_PATH);
-    return false;
-  }
-  if (!SdchManager::secure_scheme_supported() &&
-      referring_url.SchemeIsSecure()) {
-    SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME);
-    return false;
-  }
-  if (referring_url.SchemeIsSecure() != url_.SchemeIsSecure()) {
-    SdchErrorRecovery(DICTIONARY_FOUND_HAS_WRONG_SCHEME);
-    return false;
-  }
+  if (!DomainMatch(referring_url, domain_))
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_DOMAIN;
+
+  if (!ports_.empty() && 0 == ports_.count(referring_url.EffectiveIntPort()))
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_PORT_LIST;
+
+  if (path_.size() && !PathMatch(referring_url.path(), path_))
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_PATH;
+
+  if (!SdchManager::secure_scheme_supported() && referring_url.SchemeIsSecure())
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
+
+  if (referring_url.SchemeIsSecure() != url_.SchemeIsSecure())
+    return SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME;
 
   // TODO(jar): Remove overly restrictive failsafe test (added per security
   // review) when we have a need to be more general.
-  if (!referring_url.SchemeIsHTTPOrHTTPS()) {
-    SdchErrorRecovery(ATTEMPT_TO_DECODE_NON_HTTP_DATA);
-    return false;
-  }
+  if (!referring_url.SchemeIsHTTPOrHTTPS())
+    return SDCH_ATTEMPT_TO_DECODE_NON_HTTP_DATA;
 
-  return true;
+  return SDCH_OK;
 }
 
+// static
 bool SdchManager::Dictionary::PathMatch(const std::string& path,
                                         const std::string& restriction) {
   /*  Must be either:
@@ -268,8 +255,9 @@
 }
 
 // static
-void SdchManager::SdchErrorRecovery(ProblemCodes problem) {
-  UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_4", problem, MAX_PROBLEM_CODE);
+void SdchManager::SdchErrorRecovery(SdchProblemCode problem) {
+  UMA_HISTOGRAM_ENUMERATION("Sdch3.ProblemCodes_5", problem,
+                            SDCH_MAX_PROBLEM_CODE);
 }
 
 // static
@@ -283,7 +271,7 @@
 }
 
 void SdchManager::BlacklistDomain(const GURL& url,
-                                  ProblemCodes blacklist_reason) {
+                                  SdchProblemCode blacklist_reason) {
   SetAllowLatencyExperiment(url, false);
 
   BlacklistInfo* blacklist_info =
@@ -304,7 +292,7 @@
 }
 
 void SdchManager::BlacklistDomainForever(const GURL& url,
-                                         ProblemCodes blacklist_reason) {
+                                         SdchProblemCode blacklist_reason) {
   SetAllowLatencyExperiment(url, false);
 
   BlacklistInfo* blacklist_info =
@@ -322,7 +310,7 @@
   BlacklistInfo* blacklist_info = &blacklisted_domains_[
       base::StringToLowerASCII(domain)];
   blacklist_info->count = 0;
-  blacklist_info->reason = MIN_PROBLEM_CODE;
+  blacklist_info->reason = SDCH_OK;
 }
 
 int SdchManager::BlackListDomainCount(const std::string& domain) {
@@ -341,49 +329,53 @@
   return blacklisted_domains_[domain_lower].exponential_count;
 }
 
-bool SdchManager::IsInSupportedDomain(const GURL& url) {
+SdchProblemCode SdchManager::IsInSupportedDomain(const GURL& url) {
   DCHECK(thread_checker_.CalledOnValidThread());
   if (!g_sdch_enabled_ )
-    return false;
+    return SDCH_DISABLED;
 
   if (!secure_scheme_supported() && url.SchemeIsSecure())
-    return false;
+    return SDCH_SECURE_SCHEME_NOT_SUPPORTED;
 
   if (blacklisted_domains_.empty())
-    return true;
+    return SDCH_OK;
 
   DomainBlacklistInfo::iterator it =
       blacklisted_domains_.find(base::StringToLowerASCII(url.host()));
   if (blacklisted_domains_.end() == it || it->second.count == 0)
-    return true;
+    return SDCH_OK;
 
   UMA_HISTOGRAM_ENUMERATION("Sdch3.BlacklistReason", it->second.reason,
-                            MAX_PROBLEM_CODE);
-  SdchErrorRecovery(DOMAIN_BLACKLIST_INCLUDES_TARGET);
+                            SDCH_MAX_PROBLEM_CODE);
 
   int count = it->second.count - 1;
   if (count > 0) {
     it->second.count = count;
   } else {
     it->second.count = 0;
-    it->second.reason = MIN_PROBLEM_CODE;
+    it->second.reason = SDCH_OK;
   }
 
-  return false;
+  return SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET;
 }
 
-void SdchManager::OnGetDictionary(const GURL& request_url,
-                                  const GURL& dictionary_url) {
-  if (!CanFetchDictionary(request_url, dictionary_url))
-    return;
+SdchProblemCode SdchManager::OnGetDictionary(const GURL& request_url,
+                                             const GURL& dictionary_url) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  SdchProblemCode rv = CanFetchDictionary(request_url, dictionary_url);
+  if (rv != SDCH_OK)
+    return rv;
 
   FOR_EACH_OBSERVER(SdchObserver,
                     observers_,
                     OnGetDictionary(this, request_url, dictionary_url));
+
+  return SDCH_OK;
 }
 
-bool SdchManager::CanFetchDictionary(const GURL& referring_url,
-                                     const GURL& dictionary_url) const {
+SdchProblemCode SdchManager::CanFetchDictionary(
+    const GURL& referring_url,
+    const GURL& dictionary_url) const {
   DCHECK(thread_checker_.CalledOnValidThread());
   /* The user agent may retrieve a dictionary from the dictionary URL if all of
      the following are true:
@@ -397,41 +389,40 @@
   // Item (1) above implies item (2).  Spec should be updated.
   // I take "host name match" to be "is identical to"
   if (referring_url.host() != dictionary_url.host() ||
-      referring_url.scheme() != dictionary_url.scheme()) {
-    SdchErrorRecovery(DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST);
-    return false;
-  }
-  if (!secure_scheme_supported() && referring_url.SchemeIsSecure()) {
-    SdchErrorRecovery(DICTIONARY_SELECTED_FOR_SSL);
-    return false;
-  }
+      referring_url.scheme() != dictionary_url.scheme())
+    return SDCH_DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST;
+
+  if (!secure_scheme_supported() && referring_url.SchemeIsSecure())
+    return SDCH_DICTIONARY_SELECTED_FOR_SSL;
 
   // TODO(jar): Remove this failsafe conservative hack which is more restrictive
   // than current SDCH spec when needed, and justified by security audit.
-  if (!referring_url.SchemeIsHTTPOrHTTPS()) {
-    SdchErrorRecovery(DICTIONARY_SELECTED_FROM_NON_HTTP);
-    return false;
-  }
+  if (!referring_url.SchemeIsHTTPOrHTTPS())
+    return SDCH_DICTIONARY_SELECTED_FROM_NON_HTTP;
 
-  return true;
+  return SDCH_OK;
 }
 
-void SdchManager::GetVcdiffDictionary(
+SdchProblemCode SdchManager::GetVcdiffDictionary(
     const std::string& server_hash,
     const GURL& referring_url,
     scoped_refptr<Dictionary>* dictionary) {
   DCHECK(thread_checker_.CalledOnValidThread());
   *dictionary = NULL;
   DictionaryMap::iterator it = dictionaries_.find(server_hash);
-  if (it == dictionaries_.end()) {
-    return;
-  }
+  if (it == dictionaries_.end())
+    return SDCH_DICTIONARY_HASH_NOT_FOUND;
+
   scoped_refptr<Dictionary> matching_dictionary = it->second;
-  if (!IsInSupportedDomain(referring_url))
-    return;
-  if (!matching_dictionary->CanUse(referring_url))
-    return;
-  *dictionary = matching_dictionary;
+
+  SdchProblemCode rv = IsInSupportedDomain(referring_url);
+  if (rv != SDCH_OK)
+    return rv;
+
+  rv = matching_dictionary->CanUse(referring_url);
+  if (rv == SDCH_OK)
+    *dictionary = matching_dictionary;
+  return rv;
 }
 
 // TODO(jar): If we have evictions from the dictionaries_, then we need to
@@ -443,9 +434,11 @@
   int count = 0;
   for (DictionaryMap::iterator it = dictionaries_.begin();
        it != dictionaries_.end(); ++it) {
-    if (!IsInSupportedDomain(target_url))
+    SdchProblemCode rv = IsInSupportedDomain(target_url);
+    if (rv != SDCH_OK)
       continue;
-    if (!it->second->CanAdvertise(target_url))
+
+    if (it->second->CanAdvertise(target_url) != SDCH_OK)
       continue;
     ++count;
     if (!list->empty())
@@ -490,7 +483,7 @@
   ExperimentSet::iterator it = allow_latency_experiment_.find(url.host());
   if (allow_latency_experiment_.end() == it)
     return;  // It was already erased, or never allowed.
-  SdchErrorRecovery(LATENCY_TEST_DISALLOWED);
+  SdchErrorRecovery(SDCH_LATENCY_TEST_DISALLOWED);
   allow_latency_experiment_.erase(it);
 }
 
@@ -502,31 +495,27 @@
   observers_.RemoveObserver(observer);
 }
 
-void SdchManager::AddSdchDictionary(const std::string& dictionary_text,
+SdchProblemCode SdchManager::AddSdchDictionary(
+    const std::string& dictionary_text,
     const GURL& dictionary_url) {
   DCHECK(thread_checker_.CalledOnValidThread());
   std::string client_hash;
   std::string server_hash;
   GenerateHash(dictionary_text, &client_hash, &server_hash);
-  if (dictionaries_.find(server_hash) != dictionaries_.end()) {
-    SdchErrorRecovery(DICTIONARY_ALREADY_LOADED);
-    return;                             // Already loaded.
-  }
+  if (dictionaries_.find(server_hash) != dictionaries_.end())
+    return SDCH_DICTIONARY_ALREADY_LOADED;  // Already loaded.
 
   std::string domain, path;
   std::set<int> ports;
   base::Time expiration(base::Time::Now() + base::TimeDelta::FromDays(30));
 
-  if (dictionary_text.empty()) {
-    SdchErrorRecovery(DICTIONARY_HAS_NO_TEXT);
-    return;                             // Missing header.
-  }
+  if (dictionary_text.empty())
+    return SDCH_DICTIONARY_HAS_NO_TEXT;  // Missing header.
 
   size_t header_end = dictionary_text.find("\n\n");
-  if (std::string::npos == header_end) {
-    SdchErrorRecovery(DICTIONARY_HAS_NO_HEADER);
-    return;                             // Missing header.
-  }
+  if (std::string::npos == header_end)
+    return SDCH_DICTIONARY_HAS_NO_HEADER;  // Missing header.
+
   size_t line_start = 0;  // Start of line being parsed.
   while (1) {
     size_t line_end = dictionary_text.find('\n', line_start);
@@ -534,10 +523,9 @@
     DCHECK_LE(line_end, header_end);
 
     size_t colon_index = dictionary_text.find(':', line_start);
-    if (std::string::npos == colon_index) {
-      SdchErrorRecovery(DICTIONARY_HEADER_LINE_MISSING_COLON);
-      return;                         // Illegal line missing a colon.
-    }
+    if (std::string::npos == colon_index)
+      return SDCH_DICTIONARY_HEADER_LINE_MISSING_COLON;  // Illegal line missing
+                                                         // a colon.
 
     if (colon_index > line_end)
       break;
@@ -556,7 +544,7 @@
         path = value;
       } else if (name == "format-version") {
         if (value != "1.0")
-          return;
+          return SDCH_DICTIONARY_UNSUPPORTED_VERSION;
       } else if (name == "max-age") {
         int64 seconds;
         base::StringToInt64(value, &seconds);
@@ -578,24 +566,23 @@
   GURL dictionary_url_normalized(dictionary_url);
   StripTrailingDot(&dictionary_url_normalized);
 
-  if (!IsInSupportedDomain(dictionary_url_normalized))
-    return;
+  SdchProblemCode rv = IsInSupportedDomain(dictionary_url_normalized);
+  if (rv != SDCH_OK)
+    return rv;
 
-  if (!Dictionary::CanSet(domain, path, ports, dictionary_url_normalized))
-    return;
+  rv = Dictionary::CanSet(domain, path, ports, dictionary_url_normalized);
+  if (rv != SDCH_OK)
+    return rv;
 
   // TODO(jar): Remove these hacks to preclude a DOS attack involving piles of
   // useless dictionaries.  We should probably have a cache eviction plan,
   // instead of just blocking additions.  For now, with the spec in flux, it
   // is probably not worth doing eviction handling.
-  if (kMaxDictionarySize < dictionary_text.size()) {
-    SdchErrorRecovery(DICTIONARY_IS_TOO_LARGE);
-    return;
-  }
-  if (kMaxDictionaryCount <= dictionaries_.size()) {
-    SdchErrorRecovery(DICTIONARY_COUNT_EXCEEDED);
-    return;
-  }
+  if (kMaxDictionarySize < dictionary_text.size())
+    return SDCH_DICTIONARY_IS_TOO_LARGE;
+
+  if (kMaxDictionaryCount <= dictionaries_.size())
+    return SDCH_DICTIONARY_COUNT_EXCEEDED;
 
   UMA_HISTOGRAM_COUNTS("Sdch3.Dictionary size loaded", dictionary_text.size());
   DVLOG(1) << "Loaded dictionary with client hash " << client_hash
@@ -605,7 +592,7 @@
                      dictionary_url_normalized, domain,
                      path, expiration, ports);
   dictionaries_[server_hash] = dictionary;
-  return;
+  return SDCH_OK;
 }
 
 // static
@@ -618,4 +605,46 @@
   std::replace(output->begin(), output->end(), '/', '_');
 }
 
+base::Value* SdchManager::SdchInfoToValue() const {
+  base::DictionaryValue* value = new base::DictionaryValue();
+
+  value->SetBoolean("sdch_enabled", sdch_enabled());
+  value->SetBoolean("secure_scheme_support", secure_scheme_supported());
+
+  base::ListValue* entry_list = new base::ListValue();
+  for (DictionaryMap::const_iterator it = dictionaries_.begin();
+       it != dictionaries_.end(); ++it) {
+    base::DictionaryValue* entry_dict = new base::DictionaryValue();
+    entry_dict->SetString("url", it->second->url().spec());
+    entry_dict->SetString("client_hash", it->second->client_hash());
+    entry_dict->SetString("domain", it->second->domain());
+    entry_dict->SetString("path", it->second->path());
+    base::ListValue* port_list = new base::ListValue();
+    for (std::set<int>::const_iterator port_it = it->second->ports().begin();
+         port_it != it->second->ports().end(); ++port_it) {
+      port_list->AppendInteger(*port_it);
+    }
+    entry_dict->Set("ports", port_list);
+    entry_dict->SetString("server_hash", it->first);
+    entry_list->Append(entry_dict);
+  }
+  value->Set("dictionaries", entry_list);
+
+  entry_list = new base::ListValue();
+  for (DomainBlacklistInfo::const_iterator it = blacklisted_domains_.begin();
+       it != blacklisted_domains_.end(); ++it) {
+    if (it->second.count == 0)
+      continue;
+    base::DictionaryValue* entry_dict = new base::DictionaryValue();
+    entry_dict->SetString("domain", it->first);
+    if (it->second.count != INT_MAX)
+      entry_dict->SetInteger("tries", it->second.count);
+    entry_dict->SetInteger("reason", it->second.reason);
+    entry_list->Append(entry_dict);
+  }
+  value->Set("blacklisted", entry_list);
+
+  return value;
+}
+
 }  // namespace net
diff --git a/net/base/sdch_manager.h b/net/base/sdch_manager.h
index ff157e5..016978a 100644
--- a/net/base/sdch_manager.h
+++ b/net/base/sdch_manager.h
@@ -16,8 +16,13 @@
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "net/base/net_export.h"
+#include "net/base/sdch_problem_codes.h"
 #include "url/gurl.h"
 
+namespace base {
+class Value;
+}
+
 namespace net {
 
 class SdchObserver;
@@ -35,106 +40,6 @@
 // module) to decompress data.
 class NET_EXPORT SdchManager {
  public:
-  // A list of errors that appeared and were either resolved, or used to turn
-  // off sdch encoding.
-  enum ProblemCodes {
-    MIN_PROBLEM_CODE,
-
-    // Content-encoding correction problems.
-    ADDED_CONTENT_ENCODING = 1,
-    FIXED_CONTENT_ENCODING = 2,
-    FIXED_CONTENT_ENCODINGS = 3,
-
-    // Content decoding errors.
-    DECODE_HEADER_ERROR = 4,
-    DECODE_BODY_ERROR = 5,
-
-    // More content-encoding correction problems.
-    OPTIONAL_GUNZIP_ENCODING_ADDED = 6,
-
-    // Content encoding correction when we're not even tagged as HTML!?!
-    BINARY_ADDED_CONTENT_ENCODING = 7,
-    BINARY_FIXED_CONTENT_ENCODING = 8,
-    BINARY_FIXED_CONTENT_ENCODINGS = 9,
-
-    // Dictionary selection for use problems.
-    DICTIONARY_FOUND_HAS_WRONG_DOMAIN = 10,
-    DICTIONARY_FOUND_HAS_WRONG_PORT_LIST = 11,
-    DICTIONARY_FOUND_HAS_WRONG_PATH = 12,
-    DICTIONARY_FOUND_HAS_WRONG_SCHEME = 13,
-    DICTIONARY_HASH_NOT_FOUND = 14,
-    DICTIONARY_HASH_MALFORMED = 15,
-
-    // Dictionary saving problems.
-    DICTIONARY_HAS_NO_HEADER = 20,
-    DICTIONARY_HEADER_LINE_MISSING_COLON = 21,
-    DICTIONARY_MISSING_DOMAIN_SPECIFIER = 22,
-    DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN = 23,
-    DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL = 24,
-    DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL = 25,
-    DICTIONARY_HAS_NO_TEXT = 26,
-    DICTIONARY_REFERER_URL_HAS_DOT_IN_PREFIX = 27,
-
-    // Dictionary loading problems.
-    DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST = 30,
-    DICTIONARY_SELECTED_FOR_SSL = 31,
-    DICTIONARY_ALREADY_LOADED = 32,
-    DICTIONARY_SELECTED_FROM_NON_HTTP = 33,
-    DICTIONARY_IS_TOO_LARGE= 34,
-    DICTIONARY_COUNT_EXCEEDED = 35,
-    DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD = 36,
-    DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD = 37,
-    DICTIONARY_FETCH_READ_FAILED = 38,
-
-    // Failsafe hack.
-    ATTEMPT_TO_DECODE_NON_HTTP_DATA = 40,
-
-
-    // Content-Encoding problems detected, with no action taken.
-    MULTIENCODING_FOR_NON_SDCH_REQUEST = 50,
-    SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST = 51,
-
-    // Dictionary manager issues.
-    DOMAIN_BLACKLIST_INCLUDES_TARGET = 61,
-
-    // Problematic decode recovery methods.
-    META_REFRESH_RECOVERY = 70,            // Dictionary not found.
-    // defunct =  71, // Almost the same as META_REFRESH_UNSUPPORTED.
-    // defunct = 72,  // Almost the same as CACHED_META_REFRESH_UNSUPPORTED.
-    // defunct = 73,  // PASSING_THROUGH_NON_SDCH plus
-                      // RESPONSE_TENTATIVE_SDCH in ../filter/sdch_filter.cc.
-    META_REFRESH_UNSUPPORTED = 74,         // Unrecoverable error.
-    CACHED_META_REFRESH_UNSUPPORTED = 75,  // As above, but pulled from cache.
-    PASSING_THROUGH_NON_SDCH = 76,  // Tagged sdch but missing dictionary-hash.
-    INCOMPLETE_SDCH_CONTENT = 77,   // Last window was not completely decoded.
-    PASS_THROUGH_404_CODE = 78,     // URL not found message passing through.
-
-    // This next report is very common, and not really an error scenario, but
-    // it exercises the error recovery logic.
-    PASS_THROUGH_OLD_CACHED = 79,   // Back button got pre-SDCH cached content.
-
-    // Common decoded recovery methods.
-    META_REFRESH_CACHED_RECOVERY = 80,  // Probably startup tab loading.
-    // defunct = 81, // Now tracked by ResponseCorruptionDetectionCause histo.
-
-    // Non SDCH problems, only accounted for to make stat counting complete
-    // (i.e., be able to be sure all dictionary advertisements are accounted
-    // for).
-
-    UNFLUSHED_CONTENT = 90,    // Possible error in filter chaining.
-    // defunct = 91,           // MISSING_TIME_STATS (Should never happen.)
-    CACHE_DECODED = 92,        // No timing stats recorded.
-    // defunct = 93,           // OVER_10_MINUTES (No timing stats recorded.)
-    UNINITIALIZED = 94,        // Filter never even got initialized.
-    PRIOR_TO_DICTIONARY = 95,  // We hadn't even parsed a dictionary selector.
-    DECODE_ERROR = 96,         // Something went wrong during decode.
-
-    // Problem during the latency test.
-    LATENCY_TEST_DISALLOWED = 100,  // SDCH now failing, but it worked before!
-
-    MAX_PROBLEM_CODE  // Used to bound histogram.
-  };
-
   // Use the following static limits to block DOS attacks until we implement
   // a cached dictionary evicition strategy.
   static const size_t kMaxDictionarySize;
@@ -167,19 +72,25 @@
 
     const GURL& url() const { return url_; }
     const std::string& client_hash() const { return client_hash_; }
+    const std::string& domain() const { return domain_; }
+    const std::string& path() const { return path_; }
+    const base::Time& expiration() const { return expiration_; }
+    const std::set<int>& ports() const { return ports_; }
 
     // Security method to check if we can advertise this dictionary for use
     // if the |target_url| returns SDCH compressed data.
-    bool CanAdvertise(const GURL& target_url);
+    SdchProblemCode CanAdvertise(const GURL& target_url) const;
 
     // Security methods to check if we can establish a new dictionary with the
     // given data, that arrived in response to get of dictionary_url.
-    static bool CanSet(const std::string& domain, const std::string& path,
-                       const std::set<int>& ports, const GURL& dictionary_url);
+    static SdchProblemCode CanSet(const std::string& domain,
+                                  const std::string& path,
+                                  const std::set<int>& ports,
+                                  const GURL& dictionary_url);
 
     // Security method to check if we can use a dictionary to decompress a
     // target that arrived with a reference to this dictionary.
-    bool CanUse(const GURL& referring_url);
+    SdchProblemCode CanUse(const GURL& referring_url) const;
 
     // Compare paths to see if they "match" for dictionary use.
     static bool PathMatch(const std::string& path,
@@ -188,7 +99,6 @@
     // Compare domains to see if the "match" for dictionary use.
     static bool DomainMatch(const GURL& url, const std::string& restriction);
 
-
     // The actual text of the dictionary.
     std::string text_;
 
@@ -218,7 +128,7 @@
   void ClearData();
 
   // Record stats on various errors.
-  static void SdchErrorRecovery(ProblemCodes problem);
+  static void SdchErrorRecovery(SdchProblemCode problem);
 
   // Enables or disables SDCH compression.
   static void EnableSdchSupport(bool enabled);
@@ -237,11 +147,12 @@
   // Used when filter errors are found from a given domain, but it is plausible
   // that the cause is temporary (such as application startup, where cached
   // entries are used, but a dictionary is not yet loaded).
-  void BlacklistDomain(const GURL& url, ProblemCodes blacklist_reason);
+  void BlacklistDomain(const GURL& url, SdchProblemCode blacklist_reason);
 
   // Used when SEVERE filter errors are found from a given domain, to prevent
   // further use of SDCH on that domain.
-  void BlacklistDomainForever(const GURL& url, ProblemCodes blacklist_reason);
+  void BlacklistDomainForever(const GURL& url,
+                              SdchProblemCode blacklist_reason);
 
   // Unit test only, this function resets enabling of sdch, and clears the
   // blacklist.
@@ -260,11 +171,12 @@
   // supported domain (i.e., not blacklisted, and either the specific supported
   // domain, or all domains were assumed supported). If it is blacklist, reduce
   // by 1 the number of times it will be reported as blacklisted.
-  bool IsInSupportedDomain(const GURL& url);
+  SdchProblemCode IsInSupportedDomain(const GURL& url);
 
   // Send out appropriate events notifying observers that a Get-Dictionary
   // header has been seen.
-  void OnGetDictionary(const GURL& request_url, const GURL& dictionary_url);
+  SdchProblemCode OnGetDictionary(const GURL& request_url,
+                                  const GURL& dictionary_url);
 
   // Find the vcdiff dictionary (the body of the sdch dictionary that appears
   // after the meta-data headers like Domain:...) with the given |server_hash|
@@ -272,9 +184,12 @@
   // be sure the returned |dictionary| can be used for decoding content supplied
   // in response to a request for |referring_url|.
   // Return null in |dictionary| if there is no matching legal dictionary.
-  void GetVcdiffDictionary(const std::string& server_hash,
-                           const GURL& referring_url,
-                           scoped_refptr<Dictionary>* dictionary);
+  // Returns SDCH_OK if dictionary is not found, SDCH(-over-https) is disabled,
+  // or if matching legal dictionary exists. Otherwise returns the
+  // corresponding problem code.
+  SdchProblemCode GetVcdiffDictionary(const std::string& server_hash,
+                                      const GURL& referring_url,
+                                      scoped_refptr<Dictionary>* dictionary);
 
   // Get list of available (pre-cached) dictionaries that we have already loaded
   // into memory. The list is a comma separated list of (client) hashes per
@@ -295,12 +210,16 @@
 
   void SetAllowLatencyExperiment(const GURL& url, bool enable);
 
+  base::Value* SdchInfoToValue() const;
+
   // Add an SDCH dictionary to our list of availible
   // dictionaries. This addition will fail if addition is illegal
   // (data in the dictionary is not acceptable from the
   // dictionary_url; dictionary already added, etc.).
-  void AddSdchDictionary(const std::string& dictionary_text,
-                         const GURL& dictionary_url);
+  // Returns SDCH_OK if the addition was successfull, and corresponding error
+  // code otherwise.
+  SdchProblemCode AddSdchDictionary(const std::string& dictionary_text,
+                                    const GURL& dictionary_url);
 
   // Registration for events generated by the SDCH subsystem.
   void AddObserver(SdchObserver* observer);
@@ -308,24 +227,20 @@
 
  private:
   struct BlacklistInfo {
-    BlacklistInfo()
-        : count(0),
-          exponential_count(0),
-          reason(MIN_PROBLEM_CODE) {}
+    BlacklistInfo() : count(0), exponential_count(0), reason(SDCH_OK) {}
 
-    int count;                   // # of times to refuse SDCH advertisement.
-    int exponential_count;       // Current exponential backoff ratchet.
-    ProblemCodes reason;         // Why domain was blacklisted.
-
+    int count;               // # of times to refuse SDCH advertisement.
+    int exponential_count;   // Current exponential backoff ratchet.
+    SdchProblemCode reason;  // Why domain was blacklisted.
   };
   typedef std::map<std::string, BlacklistInfo> DomainBlacklistInfo;
   typedef std::set<std::string> ExperimentSet;
 
   // Determines whether a "Get-Dictionary" header is legal (dictionary
   // url has appropriate relationship to referrer url) in the SDCH
-  // protocol.  Return true if fetch is legal.
-  bool CanFetchDictionary(const GURL& referring_url,
-                          const GURL& dictionary_url) const;
+  // protocol.  Return SDCH_OK if fetch is legal.
+  SdchProblemCode CanFetchDictionary(const GURL& referring_url,
+                                     const GURL& dictionary_url) const;
 
   // A map of dictionaries info indexed by the hash that the server provides.
   typedef std::map<std::string, scoped_refptr<Dictionary> > DictionaryMap;
@@ -340,6 +255,7 @@
   // A simple implementation of a RFC 3548 "URL safe" base64 encoder.
   static void UrlSafeBase64Encode(const std::string& input,
                                   std::string* output);
+
   DictionaryMap dictionaries_;
 
   // List domains where decode failures have required disabling sdch.
diff --git a/net/base/sdch_manager_unittest.cc b/net/base/sdch_manager_unittest.cc
index d986879..c20be58 100644
--- a/net/base/sdch_manager_unittest.cc
+++ b/net/base/sdch_manager_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "net/base/net_log.h"
 #include "net/base/sdch_manager.h"
 #include "net/base/sdch_observer.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -73,14 +74,7 @@
   // failure.
   bool AddSdchDictionary(const std::string& dictionary_text,
                          const GURL& gurl) {
-    std::string list;
-    sdch_manager_->GetAvailDictionaryList(gurl, &list);
-    sdch_manager_->AddSdchDictionary(dictionary_text, gurl);
-    std::string list2;
-    sdch_manager_->GetAvailDictionaryList(gurl, &list2);
-
-    // The list of hashes should change iff the addition succeeds.
-    return (list != list2);
+    return sdch_manager_->AddSdchDictionary(dictionary_text, gurl) == SDCH_OK;
   }
 
  private:
@@ -105,31 +99,34 @@
   GURL google_url("http://www.google.com");
 
   SdchManager::EnableSdchSupport(false);
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(google_url));
+  EXPECT_EQ(SDCH_DISABLED, sdch_manager()->IsInSupportedDomain(google_url));
   SdchManager::EnableSdchSupport(true);
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(google_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(google_url));
 }
 
 TEST_F(SdchManagerTest, DomainBlacklisting) {
   GURL test_url("http://www.test.com");
   GURL google_url("http://www.google.com");
 
-  sdch_manager()->BlacklistDomain(test_url, SdchManager::MIN_PROBLEM_CODE);
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(test_url));
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(google_url));
+  sdch_manager()->BlacklistDomain(test_url, SDCH_OK);
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager()->IsInSupportedDomain(test_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(google_url));
 
-  sdch_manager()->BlacklistDomain(google_url, SdchManager::MIN_PROBLEM_CODE);
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(google_url));
+  sdch_manager()->BlacklistDomain(google_url, SDCH_OK);
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager()->IsInSupportedDomain(google_url));
 }
 
 TEST_F(SdchManagerTest, DomainBlacklistingCaseSensitivity) {
   GURL test_url("http://www.TesT.com");
   GURL test2_url("http://www.tEst.com");
 
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(test_url));
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(test2_url));
-  sdch_manager()->BlacklistDomain(test_url, SdchManager::MIN_PROBLEM_CODE);
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(test2_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(test_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(test2_url));
+  sdch_manager()->BlacklistDomain(test_url, SDCH_OK);
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager()->IsInSupportedDomain(test2_url));
 }
 
 TEST_F(SdchManagerTest, BlacklistingReset) {
@@ -139,7 +136,7 @@
   sdch_manager()->ClearBlacklistings();
   EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
   EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 0);
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(gurl));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl));
 }
 
 TEST_F(SdchManagerTest, BlacklistingSingleBlacklist) {
@@ -147,14 +144,15 @@
   std::string domain(gurl.host());
   sdch_manager()->ClearBlacklistings();
 
-  sdch_manager()->BlacklistDomain(gurl, SdchManager::MIN_PROBLEM_CODE);
+  sdch_manager()->BlacklistDomain(gurl, SDCH_OK);
   EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 1);
   EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), 1);
 
   // Check that any domain lookup reduces the blacklist counter.
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(gurl));
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager()->IsInSupportedDomain(gurl));
   EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(gurl));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl));
 }
 
 TEST_F(SdchManagerTest, BlacklistingExponential) {
@@ -164,18 +162,19 @@
 
   int exponential = 1;
   for (int i = 1; i < 100; ++i) {
-    sdch_manager()->BlacklistDomain(gurl, SdchManager::MIN_PROBLEM_CODE);
+    sdch_manager()->BlacklistDomain(gurl, SDCH_OK);
     EXPECT_EQ(sdch_manager()->BlacklistDomainExponential(domain), exponential);
 
     EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential);
-    EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(gurl));
+    EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+              sdch_manager()->IsInSupportedDomain(gurl));
     EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), exponential - 1);
 
     // Simulate a large number of domain checks (which eventually remove the
     // blacklisting).
     sdch_manager()->ClearDomainBlacklisting(domain);
     EXPECT_EQ(sdch_manager()->BlackListDomainCount(domain), 0);
-    EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(gurl));
+    EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(gurl));
 
     // Predict what exponential backoff will be.
     exponential = 1 + 2 * exponential;
@@ -246,7 +245,8 @@
   std::string client_hash;
   std::string server_hash;
   sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
-  sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
+  EXPECT_EQ(SDCH_OK, sdch_manager()->GetVcdiffDictionary(
+                         server_hash, target_url, &dictionary));
   EXPECT_TRUE(dictionary.get() != NULL);
 }
 
@@ -269,7 +269,9 @@
   std::string client_hash;
   std::string server_hash;
   sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
-  sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
+  EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME,
+            sdch_manager()->GetVcdiffDictionary(server_hash, target_url,
+                                                &dictionary));
   EXPECT_TRUE(dictionary.get() == NULL);
 }
 
@@ -292,7 +294,9 @@
   std::string client_hash;
   std::string server_hash;
   sdch_manager()->GenerateHash(dictionary_text, &client_hash, &server_hash);
-  sdch_manager()->GetVcdiffDictionary(server_hash, target_url, &dictionary);
+  EXPECT_EQ(SDCH_DICTIONARY_FOUND_HAS_WRONG_SCHEME,
+            sdch_manager()->GetVcdiffDictionary(server_hash, target_url,
+                                                &dictionary));
   EXPECT_TRUE(dictionary.get() == NULL);
 }
 
@@ -516,10 +520,10 @@
   EXPECT_TRUE(AddSdchDictionary(dictionary_text_1,
                                 GURL("http://" + dictionary_domain_1)));
   scoped_refptr<SdchManager::Dictionary> dictionary;
-  sdch_manager()->GetVcdiffDictionary(
-      server_hash_1,
-      GURL("http://" + dictionary_domain_1 + "/random_url"),
-      &dictionary);
+  EXPECT_EQ(SDCH_OK, sdch_manager()->GetVcdiffDictionary(
+                         server_hash_1,
+                         GURL("http://" + dictionary_domain_1 + "/random_url"),
+                         &dictionary));
   EXPECT_TRUE(dictionary.get());
 
   second_manager.AddSdchDictionary(
@@ -530,16 +534,18 @@
       &dictionary);
   EXPECT_TRUE(dictionary.get());
 
-  sdch_manager()->GetVcdiffDictionary(
-      server_hash_2,
-      GURL("http://" + dictionary_domain_2 + "/random_url"),
-      &dictionary);
+  EXPECT_EQ(
+      SDCH_DICTIONARY_HASH_NOT_FOUND,
+      sdch_manager()->GetVcdiffDictionary(
+          server_hash_2, GURL("http://" + dictionary_domain_2 + "/random_url"),
+          &dictionary));
   EXPECT_FALSE(dictionary.get());
 
-  second_manager.GetVcdiffDictionary(
-      server_hash_1,
-      GURL("http://" + dictionary_domain_1 + "/random_url"),
-      &dictionary);
+  EXPECT_EQ(
+      SDCH_DICTIONARY_HASH_NOT_FOUND,
+      second_manager.GetVcdiffDictionary(
+          server_hash_1, GURL("http://" + dictionary_domain_1 + "/random_url"),
+          &dictionary));
   EXPECT_FALSE(dictionary.get());
 }
 
@@ -549,14 +555,15 @@
 
   bool expect_https_support = true;
 
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
-  EXPECT_EQ(expect_https_support,
-            sdch_manager()->IsInSupportedDomain(secure_url));
+  SdchProblemCode expected_code =
+      expect_https_support ? SDCH_OK : SDCH_SECURE_SCHEME_NOT_SUPPORTED;
+
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(url));
+  EXPECT_EQ(expected_code, sdch_manager()->IsInSupportedDomain(secure_url));
 
   SdchManager::EnableSecureSchemeSupport(!expect_https_support);
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(url));
-  EXPECT_NE(expect_https_support,
-            sdch_manager()->IsInSupportedDomain(secure_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(url));
+  EXPECT_NE(expected_code, sdch_manager()->IsInSupportedDomain(secure_url));
 }
 
 TEST_F(SdchManagerTest, ClearDictionaryData) {
@@ -572,25 +579,26 @@
   EXPECT_TRUE(AddSdchDictionary(dictionary_text,
                                 GURL("http://" + dictionary_domain)));
   scoped_refptr<SdchManager::Dictionary> dictionary;
-  sdch_manager()->GetVcdiffDictionary(
-      server_hash,
-      GURL("http://" + dictionary_domain + "/random_url"),
-      &dictionary);
+  EXPECT_EQ(SDCH_OK, sdch_manager()->GetVcdiffDictionary(
+                         server_hash,
+                         GURL("http://" + dictionary_domain + "/random_url"),
+                         &dictionary));
   EXPECT_TRUE(dictionary.get());
 
-  sdch_manager()->BlacklistDomain(GURL(blacklist_url),
-                                  SdchManager::MIN_PROBLEM_CODE);
-  EXPECT_FALSE(sdch_manager()->IsInSupportedDomain(blacklist_url));
+  sdch_manager()->BlacklistDomain(GURL(blacklist_url), SDCH_OK);
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager()->IsInSupportedDomain(blacklist_url));
 
   sdch_manager()->ClearData();
 
   dictionary = NULL;
-  sdch_manager()->GetVcdiffDictionary(
-      server_hash,
-      GURL("http://" + dictionary_domain + "/random_url"),
-      &dictionary);
+  EXPECT_EQ(
+      SDCH_DICTIONARY_HASH_NOT_FOUND,
+      sdch_manager()->GetVcdiffDictionary(
+          server_hash, GURL("http://" + dictionary_domain + "/random_url"),
+          &dictionary));
   EXPECT_FALSE(dictionary.get());
-  EXPECT_TRUE(sdch_manager()->IsInSupportedDomain(blacklist_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager()->IsInSupportedDomain(blacklist_url));
 }
 
 TEST_F(SdchManagerTest, GetDictionaryNotification) {
diff --git a/net/base/sdch_net_log_params.cc b/net/base/sdch_net_log_params.cc
new file mode 100644
index 0000000..02e0ad7
--- /dev/null
+++ b/net/base/sdch_net_log_params.cc
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/sdch_net_log_params.h"
+
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "url/gurl.h"
+
+namespace net {
+
+base::Value* NetLogSdchResourceProblemCallback(SdchProblemCode problem,
+                                               NetLog::LogLevel log_level) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetInteger("sdch_problem_code", problem);
+  dict->SetInteger("net_error", ERR_FAILED);
+  return dict;
+}
+
+base::Value* NetLogSdchDictionaryFetchProblemCallback(
+    SdchProblemCode problem,
+    const GURL& url,
+    bool is_error,
+    NetLog::LogLevel log_level) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetInteger("sdch_problem_code", problem);
+  dict->SetString("dictionary_url", url.spec());
+  if (is_error)
+    dict->SetInteger("net_error", ERR_FAILED);
+  return dict;
+}
+
+}  // namespace net
diff --git a/net/base/sdch_net_log_params.h b/net/base/sdch_net_log_params.h
new file mode 100644
index 0000000..7421a0a
--- /dev/null
+++ b/net/base/sdch_net_log_params.h
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_SDCH_NET_LOG_PARAMS_H_
+#define NET_BASE_SDCH_NET_LOG_PARAMS_H_
+
+#include <string>
+
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+#include "net/base/sdch_problem_codes.h"
+
+class GURL;
+
+namespace net {
+
+NET_EXPORT base::Value* NetLogSdchResourceProblemCallback(
+    SdchProblemCode problem,
+    NetLog::LogLevel log_level);
+
+// If |is_error| is false, "net_error" field won't be added to the JSON and the
+// event won't be painted red in the netlog.
+NET_EXPORT base::Value* NetLogSdchDictionaryFetchProblemCallback(
+    SdchProblemCode problem,
+    const GURL& url,
+    bool is_error,
+    NetLog::LogLevel log_level);
+
+}  // namespace net
+
+#endif  // NET_BASE_SDCH_NET_LOG_PARAMS_H_
diff --git a/net/base/sdch_problem_code_list.h b/net/base/sdch_problem_code_list.h
new file mode 100644
index 0000000..4efc17c
--- /dev/null
+++ b/net/base/sdch_problem_code_list.h
@@ -0,0 +1,127 @@
+// 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.
+
+// This file intentionally does not have header guards, it's included
+// inside a macro to generate enum values.
+
+// This file contains list of sdch-related problem codes.
+// No error.
+SDCH_PROBLEM_CODE(OK, 0)
+
+// Content-encoding correction problems.
+SDCH_PROBLEM_CODE(ADDED_CONTENT_ENCODING, 1)
+SDCH_PROBLEM_CODE(FIXED_CONTENT_ENCODING, 2)
+SDCH_PROBLEM_CODE(FIXED_CONTENT_ENCODINGS, 3)
+
+// Content decoding errors.
+SDCH_PROBLEM_CODE(DECODE_HEADER_ERROR, 4)
+SDCH_PROBLEM_CODE(DECODE_BODY_ERROR, 5)
+
+// More content-encoding correction problems.
+SDCH_PROBLEM_CODE(OPTIONAL_GUNZIP_ENCODING_ADDED, 6)
+
+// Content encoding correction when we're not even tagged as HTML!?!
+SDCH_PROBLEM_CODE(BINARY_ADDED_CONTENT_ENCODING, 7)
+SDCH_PROBLEM_CODE(BINARY_FIXED_CONTENT_ENCODING, 8)
+SDCH_PROBLEM_CODE(BINARY_FIXED_CONTENT_ENCODINGS, 9)
+
+// Dictionary selection for use problems.
+SDCH_PROBLEM_CODE(DICTIONARY_FOUND_HAS_WRONG_DOMAIN, 10)
+SDCH_PROBLEM_CODE(DICTIONARY_FOUND_HAS_WRONG_PORT_LIST, 11)
+SDCH_PROBLEM_CODE(DICTIONARY_FOUND_HAS_WRONG_PATH, 12)
+SDCH_PROBLEM_CODE(DICTIONARY_FOUND_HAS_WRONG_SCHEME, 13)
+SDCH_PROBLEM_CODE(DICTIONARY_HASH_NOT_FOUND, 14)
+SDCH_PROBLEM_CODE(DICTIONARY_HASH_MALFORMED, 15)
+SDCH_PROBLEM_CODE(DICTIONARY_FOUND_EXPIRED, 16)
+
+// Dictionary saving problems.
+SDCH_PROBLEM_CODE(DICTIONARY_HAS_NO_HEADER, 20)
+SDCH_PROBLEM_CODE(DICTIONARY_HEADER_LINE_MISSING_COLON, 21)
+SDCH_PROBLEM_CODE(DICTIONARY_MISSING_DOMAIN_SPECIFIER, 22)
+SDCH_PROBLEM_CODE(DICTIONARY_SPECIFIES_TOP_LEVEL_DOMAIN, 23)
+SDCH_PROBLEM_CODE(DICTIONARY_DOMAIN_NOT_MATCHING_SOURCE_URL, 24)
+SDCH_PROBLEM_CODE(DICTIONARY_PORT_NOT_MATCHING_SOURCE_URL, 25)
+SDCH_PROBLEM_CODE(DICTIONARY_HAS_NO_TEXT, 26)
+SDCH_PROBLEM_CODE(DICTIONARY_REFERER_URL_HAS_DOT_IN_PREFIX, 27)
+SDCH_PROBLEM_CODE(DICTIONARY_UNSUPPORTED_VERSION, 28)
+
+// Dictionary loading problems.
+SDCH_PROBLEM_CODE(DICTIONARY_LOAD_ATTEMPT_FROM_DIFFERENT_HOST, 30)
+SDCH_PROBLEM_CODE(DICTIONARY_SELECTED_FOR_SSL, 31)
+SDCH_PROBLEM_CODE(DICTIONARY_ALREADY_LOADED, 32)
+SDCH_PROBLEM_CODE(DICTIONARY_SELECTED_FROM_NON_HTTP, 33)
+SDCH_PROBLEM_CODE(DICTIONARY_IS_TOO_LARGE, 34)
+SDCH_PROBLEM_CODE(DICTIONARY_COUNT_EXCEEDED, 35)
+// defunct = 36, // DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD used instead.
+// defunct = 37, // DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD used instead.
+SDCH_PROBLEM_CODE(DICTIONARY_FETCH_READ_FAILED, 38)
+SDCH_PROBLEM_CODE(DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD, 39)
+
+// Failsafe hack.
+SDCH_PROBLEM_CODE(ATTEMPT_TO_DECODE_NON_HTTP_DATA, 40)
+
+// Content-Encoding problems detected, with no action taken.
+SDCH_PROBLEM_CODE(MULTIENCODING_FOR_NON_SDCH_REQUEST, 50)
+SDCH_PROBLEM_CODE(SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST, 51)
+
+// Dictionary manager issues.
+SDCH_PROBLEM_CODE(DOMAIN_BLACKLIST_INCLUDES_TARGET, 61)
+
+// Problematic decode recovery methods.
+// Dictionary not found.
+SDCH_PROBLEM_CODE(META_REFRESH_RECOVERY, 70)
+// defunct =  71, // Almost the same as META_REFRESH_UNSUPPORTED.
+// defunct = 72,  // Almost the same as CACHED_META_REFRESH_UNSUPPORTED.
+// defunct = 73,  // PASSING_THROUGH_NON_SDCH plus DISCARD_TENTATIVE_SDCH.
+// Unrecoverable error.
+SDCH_PROBLEM_CODE(META_REFRESH_UNSUPPORTED, 74)
+// As above, but pulled from cache.
+SDCH_PROBLEM_CODE(CACHED_META_REFRESH_UNSUPPORTED, 75)
+// Tagged sdch but missing dictionary-hash.
+SDCH_PROBLEM_CODE(PASSING_THROUGH_NON_SDCH, 76)
+// Last window was not completely decoded.
+SDCH_PROBLEM_CODE(INCOMPLETE_SDCH_CONTENT, 77)
+// URL not found message passing through.
+SDCH_PROBLEM_CODE(PASS_THROUGH_404_CODE, 78)
+
+// This next report is very common, and not really an error scenario, but
+// it exercises the error recovery logic.
+// Back button got pre-SDCH cached content.
+SDCH_PROBLEM_CODE(PASS_THROUGH_OLD_CACHED, 79)
+
+// Common decoded recovery methods.
+// Probably startup tab loading.
+SDCH_PROBLEM_CODE(META_REFRESH_CACHED_RECOVERY, 80)
+// defunct = 81, // Now tracked by ResponseCorruptionDetectionCause histo.
+
+// Non SDCH problems, only accounted for to make stat counting complete
+// (i.e., be able to be sure all dictionary advertisements are accounted
+// for).
+// Possible error in filter chaining.
+SDCH_PROBLEM_CODE(UNFLUSHED_CONTENT, 90)
+// defunct = 91,           // MISSING_TIME_STATS (Should never happen.)
+// No timing stats recorded.
+SDCH_PROBLEM_CODE(CACHE_DECODED, 92)
+// defunct = 93,           // OVER_10_MINUTES (No timing stats recorded.)
+// Filter never even got initialized.
+SDCH_PROBLEM_CODE(UNINITIALIZED, 94)
+// We hadn't even parsed a dictionary selector.
+SDCH_PROBLEM_CODE(PRIOR_TO_DICTIONARY, 95)
+// Something went wrong during decode.
+SDCH_PROBLEM_CODE(DECODE_ERROR, 96)
+
+// Problem during the latency test.
+// SDCH now failing, but it worked before!
+SDCH_PROBLEM_CODE(LATENCY_TEST_DISALLOWED, 100)
+
+// General SDCH problems.
+// SDCH is disabled.
+SDCH_PROBLEM_CODE(DISABLED, 105)
+// SDCH over https is disabled.
+SDCH_PROBLEM_CODE(SECURE_SCHEME_NOT_SUPPORTED, 106)
+
+// Used to bound histogram.
+SDCH_PROBLEM_CODE(MAX_PROBLEM_CODE, 110)
+
+// These values are not used in histograms.
diff --git a/net/base/sdch_problem_codes.h b/net/base/sdch_problem_codes.h
new file mode 100644
index 0000000..da979fc
--- /dev/null
+++ b/net/base/sdch_problem_codes.h
@@ -0,0 +1,20 @@
+// 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 NET_BASE_SDCH_PROBLEM_CODES_H_
+#define NET_BASE_SDCH_PROBLEM_CODES_H_
+
+namespace net {
+
+// A list of errors that appeared and were either resolved, or used to turn
+// off sdch encoding.
+enum SdchProblemCode {
+#define SDCH_PROBLEM_CODE(label, value) SDCH_##label = value,
+#include "net/base/sdch_problem_code_list.h"
+#undef SDCH_PROBLEM_CODE
+};
+
+}  // namespace net
+
+#endif  // NET_BASE_SDCH_PROBLEM_CODES_H_
diff --git a/net/filter/filter.cc b/net/filter/filter.cc
index c8a4740..c9a56bd 100644
--- a/net/filter/filter.cc
+++ b/net/filter/filter.cc
@@ -28,11 +28,14 @@
 #include "net/base/filename_util_unsafe.h"
 #include "net/base/io_buffer.h"
 #include "net/base/mime_util.h"
+#include "net/base/sdch_net_log_params.h"
 #include "net/filter/gzip_filter.h"
 #include "net/filter/sdch_filter.h"
 #include "net/url_request/url_request_context.h"
 #include "url/gurl.h"
 
+namespace net {
+
 namespace {
 
 // Filter types (using canonical lower case only):
@@ -53,9 +56,15 @@
 // Buffer size allocated when de-compressing data.
 const int kFilterBufSize = 32 * 1024;
 
-}  // namespace
+void LogSdchProblem(const FilterContext& filter_context,
+                    SdchProblemCode problem) {
+  SdchManager::SdchErrorRecovery(problem);
+  filter_context.GetNetLog().AddEvent(
+      NetLog::TYPE_SDCH_DECODING_ERROR,
+      base::Bind(&NetLogSdchResourceProblemCallback, problem));
+}
 
-namespace net {
+}  // namespace
 
 FilterContext::~FilterContext() {
 }
@@ -233,13 +242,12 @@
     // It was not an SDCH request, so we'll just record stats.
     if (1 < encoding_types->size()) {
       // Multiple filters were intended to only be used for SDCH (thus far!)
-      SdchManager::SdchErrorRecovery(
-          SdchManager::MULTIENCODING_FOR_NON_SDCH_REQUEST);
+      LogSdchProblem(filter_context, SDCH_MULTIENCODING_FOR_NON_SDCH_REQUEST);
     }
     if ((1 == encoding_types->size()) &&
         (FILTER_TYPE_SDCH == encoding_types->front())) {
-        SdchManager::SdchErrorRecovery(
-            SdchManager::SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST);
+      LogSdchProblem(filter_context,
+                     SDCH_SDCH_CONTENT_ENCODE_FOR_NON_SDCH_REQUEST);
     }
     return;
   }
@@ -259,8 +267,7 @@
     // no-op pass through filter if it doesn't get gzip headers where expected.
     if (1 == encoding_types->size()) {
       encoding_types->push_back(FILTER_TYPE_GZIP_HELPING_SDCH);
-      SdchManager::SdchErrorRecovery(
-          SdchManager::OPTIONAL_GUNZIP_ENCODING_ADDED);
+      LogSdchProblem(filter_context, SDCH_OPTIONAL_GUNZIP_ENCODING_ADDED);
     }
     return;
   }
@@ -294,14 +301,11 @@
     // Suspicious case: Advertised dictionary, but server didn't use sdch, and
     // we're HTML tagged.
     if (encoding_types->empty()) {
-      SdchManager::SdchErrorRecovery(
-          SdchManager::ADDED_CONTENT_ENCODING);
+      LogSdchProblem(filter_context, SDCH_ADDED_CONTENT_ENCODING);
     } else if (1 == encoding_types->size()) {
-      SdchManager::SdchErrorRecovery(
-          SdchManager::FIXED_CONTENT_ENCODING);
+      LogSdchProblem(filter_context, SDCH_FIXED_CONTENT_ENCODING);
     } else {
-      SdchManager::SdchErrorRecovery(
-          SdchManager::FIXED_CONTENT_ENCODINGS);
+      LogSdchProblem(filter_context, SDCH_FIXED_CONTENT_ENCODINGS);
     }
   } else {
     // Remarkable case!?!  We advertised an SDCH dictionary, content-encoding
@@ -313,14 +317,11 @@
     // start with "text/html" for some other reason??  We'll report this as a
     // fixup to a binary file, but it probably really is text/html (some how).
     if (encoding_types->empty()) {
-      SdchManager::SdchErrorRecovery(
-          SdchManager::BINARY_ADDED_CONTENT_ENCODING);
+      LogSdchProblem(filter_context, SDCH_BINARY_ADDED_CONTENT_ENCODING);
     } else if (1 == encoding_types->size()) {
-      SdchManager::SdchErrorRecovery(
-          SdchManager::BINARY_FIXED_CONTENT_ENCODING);
+      LogSdchProblem(filter_context, SDCH_BINARY_FIXED_CONTENT_ENCODING);
     } else {
-      SdchManager::SdchErrorRecovery(
-          SdchManager::BINARY_FIXED_CONTENT_ENCODINGS);
+      LogSdchProblem(filter_context, SDCH_BINARY_FIXED_CONTENT_ENCODINGS);
     }
   }
 
diff --git a/net/filter/filter.h b/net/filter/filter.h
index 37f55e2..13489ef 100644
--- a/net/filter/filter.h
+++ b/net/filter/filter.h
@@ -60,8 +60,9 @@
 
 namespace net {
 
-class URLRequestContext;
+class BoundNetLog;
 class IOBuffer;
+class URLRequestContext;
 
 //------------------------------------------------------------------------------
 // Define an interface class that allows access to contextual information
@@ -122,6 +123,9 @@
   // The following method forces the context to emit a specific set of
   // statistics as selected by the argument.
   virtual void RecordPacketStats(StatisticSelector statistic) const = 0;
+
+  // The BoundNetLog of the associated request.
+  virtual const BoundNetLog& GetNetLog() const = 0;
 };
 
 //------------------------------------------------------------------------------
diff --git a/net/filter/mock_filter_context.cc b/net/filter/mock_filter_context.cc
index e1e4793..35ab9ee 100644
--- a/net/filter/mock_filter_context.cc
+++ b/net/filter/mock_filter_context.cc
@@ -66,4 +66,8 @@
   return context_.get();
 }
 
+const BoundNetLog& MockFilterContext::GetNetLog() const {
+  return net_log_;
+}
+
 }  // namespace net
diff --git a/net/filter/mock_filter_context.h b/net/filter/mock_filter_context.h
index 8150e8b..41c9e9e 100644
--- a/net/filter/mock_filter_context.h
+++ b/net/filter/mock_filter_context.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "base/memory/scoped_ptr.h"
+#include "net/base/net_log.h"
 #include "net/filter/filter.h"
 #include "url/gurl.h"
 
@@ -73,6 +74,8 @@
 
   void RecordPacketStats(StatisticSelector statistic) const override {}
 
+  const BoundNetLog& GetNetLog() const override;
+
  private:
   int buffer_size_;
   std::string mime_type_;
@@ -85,6 +88,7 @@
   bool ok_to_call_get_url_;
   int response_code_;
   scoped_ptr<URLRequestContext> context_;
+  BoundNetLog net_log_;
 
   DISALLOW_COPY_AND_ASSIGN(MockFilterContext);
 };
diff --git a/net/filter/sdch_filter.cc b/net/filter/sdch_filter.cc
index df72367..d03ff7f 100644
--- a/net/filter/sdch_filter.cc
+++ b/net/filter/sdch_filter.cc
@@ -11,7 +11,9 @@
 
 #include "base/logging.h"
 #include "base/metrics/histogram.h"
+#include "base/values.h"
 #include "net/base/sdch_manager.h"
+#include "net/base/sdch_net_log_params.h"
 #include "net/url_request/url_request_context.h"
 
 #include "sdch/open-vcdiff/src/google/vcdecoder.h"
@@ -50,6 +52,51 @@
   RESPONSE_MAX,
 };
 
+const char* ResponseCorruptionDetectionCauseToString(
+    ResponseCorruptionDetectionCause cause) {
+  const char* cause_string = "<unknown>";
+  switch (cause) {
+    case RESPONSE_NONE:
+      cause_string = "NONE";
+      break;
+    case RESPONSE_404:
+      cause_string = "404";
+      break;
+    case RESPONSE_NOT_200:
+      cause_string = "NOT_200";
+      break;
+    case RESPONSE_OLD_UNENCODED:
+      cause_string = "OLD_UNENCODED";
+      break;
+    case RESPONSE_TENTATIVE_SDCH:
+      cause_string = "TENTATIVE_SDCH";
+      break;
+    case RESPONSE_NO_DICTIONARY:
+      cause_string = "NO_DICTIONARY";
+      break;
+    case RESPONSE_CORRUPT_SDCH:
+      cause_string = "CORRUPT_SDCH";
+      break;
+    case RESPONSE_ENCODING_LIE:
+      cause_string = "ENCODING_LIE";
+      break;
+    case RESPONSE_MAX:
+      cause_string = "<Error: max enum value>";
+      break;
+  }
+  return cause_string;
+}
+
+base::Value* NetLogSdchResponseCorruptionDetectionCallback(
+    ResponseCorruptionDetectionCause cause,
+    bool cached,
+    NetLog::LogLevel log_level) {
+  base::DictionaryValue* dict = new base::DictionaryValue();
+  dict->SetString("cause", ResponseCorruptionDetectionCauseToString(cause));
+  dict->SetBoolean("cached", cached);
+  return dict;
+}
+
 }  // namespace
 
 SdchFilter::SdchFilter(const FilterContext& filter_context)
@@ -84,12 +131,12 @@
   if (vcdiff_streaming_decoder_.get()) {
     if (!vcdiff_streaming_decoder_->FinishDecoding()) {
       decoding_status_ = DECODING_ERROR;
-      SdchManager::SdchErrorRecovery(SdchManager::INCOMPLETE_SDCH_CONTENT);
+      LogSdchProblem(SDCH_INCOMPLETE_SDCH_CONTENT);
       // Make it possible for the user to hit reload, and get non-sdch content.
       // Note this will "wear off" quickly enough, and is just meant to assure
       // in some rare case that the user is not stuck.
       url_request_context_->sdch_manager()->BlacklistDomain(
-          url_, SdchManager::INCOMPLETE_SDCH_CONTENT);
+          url_, SDCH_INCOMPLETE_SDCH_CONTENT);
       UMA_HISTOGRAM_COUNTS("Sdch3.PartialBytesIn",
            static_cast<int>(filter_context_.GetByteReadCount()));
       UMA_HISTOGRAM_COUNTS("Sdch3.PartialVcdiffIn", source_bytes_);
@@ -99,7 +146,7 @@
 
   if (!dest_buffer_excess_.empty()) {
     // Filter chaining error, or premature teardown.
-    SdchManager::SdchErrorRecovery(SdchManager::UNFLUSHED_CONTENT);
+    LogSdchProblem(SDCH_UNFLUSHED_CONTENT);
     UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBytesIn",
          static_cast<int>(filter_context_.GetByteReadCount()));
     UMA_HISTOGRAM_COUNTS("Sdch3.UnflushedBufferSize",
@@ -111,7 +158,7 @@
   if (filter_context_.IsCachedContent()) {
     // Not a real error, but it is useful to have this tally.
     // TODO(jar): Remove this stat after SDCH stability is validated.
-    SdchManager::SdchErrorRecovery(SdchManager::CACHE_DECODED);
+    LogSdchProblem(SDCH_CACHE_DECODED);
     return;  // We don't need timing stats, and we aready got ratios.
   }
 
@@ -135,15 +182,15 @@
       return;
     }
     case DECODING_UNINITIALIZED: {
-      SdchManager::SdchErrorRecovery(SdchManager::UNINITIALIZED);
+      LogSdchProblem(SDCH_UNINITIALIZED);
       return;
     }
     case WAITING_FOR_DICTIONARY_SELECTION: {
-      SdchManager::SdchErrorRecovery(SdchManager::PRIOR_TO_DICTIONARY);
+      LogSdchProblem(SDCH_PRIOR_TO_DICTIONARY);
       return;
     }
     case DECODING_ERROR: {
-      SdchManager::SdchErrorRecovery(SdchManager::DECODE_ERROR);
+      LogSdchProblem(SDCH_DECODE_ERROR);
       return;
     }
     case META_REFRESH_RECOVERY: {
@@ -210,7 +257,7 @@
         // We could be more generous, but for now, only a "NOT FOUND" code will
         // cause a pass through.  All other bad codes will fall into a
         // meta-refresh.
-        SdchManager::SdchErrorRecovery(SdchManager::PASS_THROUGH_404_CODE);
+        LogSdchProblem(SDCH_PASS_THROUGH_404_CODE);
         cause = RESPONSE_404;
         decoding_status_ = PASS_THROUGH;
       } else if (filter_context_.GetResponseCode() != 200) {
@@ -220,7 +267,7 @@
                  && !dictionary_hash_is_plausible_) {
         // We must have hit the back button, and gotten content that was fetched
         // before we *really* advertised SDCH and a dictionary.
-        SdchManager::SdchErrorRecovery(SdchManager::PASS_THROUGH_OLD_CACHED);
+        LogSdchProblem(SDCH_PASS_THROUGH_OLD_CACHED);
         decoding_status_ = PASS_THROUGH;
         cause = RESPONSE_OLD_UNENCODED;
       } else if (possible_pass_through_) {
@@ -256,11 +303,11 @@
         // though it is not!
         // Meta-refresh won't help, as we didn't advertise an SDCH dictionary!!
         // Worse yet, meta-refresh could lead to an infinite refresh loop.
-        SdchManager::SdchErrorRecovery(SdchManager::PASSING_THROUGH_NON_SDCH);
+        LogSdchProblem(SDCH_PASSING_THROUGH_NON_SDCH);
         decoding_status_ = PASS_THROUGH;
         // ... but further back-off on advertising SDCH support.
         url_request_context_->sdch_manager()->BlacklistDomain(
-            url_, SdchManager::PASSING_THROUGH_NON_SDCH);
+            url_, SDCH_PASSING_THROUGH_NON_SDCH);
         cause = RESPONSE_ENCODING_LIE;
       }
       DCHECK_NE(RESPONSE_NONE, cause);
@@ -274,6 +321,10 @@
         UMA_HISTOGRAM_ENUMERATION(
             "Sdch3.ResponseCorruptionDetection.Uncached", cause, RESPONSE_MAX);
       }
+      filter_context_.GetNetLog().AddEvent(
+          NetLog::TYPE_SDCH_RESPONSE_CORRUPTION_DETECTION,
+          base::Bind(&NetLogSdchResponseCorruptionDetectionCallback, cause,
+                     filter_context_.IsCachedContent()));
 
       if (decoding_status_ == PASS_THROUGH) {
         dest_buffer_excess_ = dictionary_hash_;  // Send what we scanned.
@@ -282,13 +333,12 @@
         if (std::string::npos == mime_type_.find("text/html")) {
           // Since we can't do a meta-refresh (along with an exponential
           // backoff), we'll just make sure this NEVER happens again.
-          SdchManager::ProblemCodes problem =
-              (filter_context_.IsCachedContent() ?
-               SdchManager::CACHED_META_REFRESH_UNSUPPORTED :
-               SdchManager::META_REFRESH_UNSUPPORTED);
+          SdchProblemCode problem = (filter_context_.IsCachedContent()
+                                         ? SDCH_CACHED_META_REFRESH_UNSUPPORTED
+                                         : SDCH_META_REFRESH_UNSUPPORTED);
           url_request_context_->sdch_manager()->BlacklistDomainForever(
               url_, problem);
-          SdchManager::SdchErrorRecovery(problem);
+          LogSdchProblem(problem);
           return FILTER_ERROR;
         }
         // HTML content means we can issue a meta-refresh, and get the content
@@ -296,14 +346,13 @@
         if (filter_context_.IsCachedContent()) {
           // Cached content is probably a startup tab, so we'll just get fresh
           // content and try again, without disabling sdch.
-          SdchManager::SdchErrorRecovery(
-              SdchManager::META_REFRESH_CACHED_RECOVERY);
+          LogSdchProblem(SDCH_META_REFRESH_CACHED_RECOVERY);
         } else {
           // Since it wasn't in the cache, we definately need at least some
           // period of blacklisting to get the correct content.
           url_request_context_->sdch_manager()->BlacklistDomain(
-              url_, SdchManager::META_REFRESH_RECOVERY);
-          SdchManager::SdchErrorRecovery(SdchManager::META_REFRESH_RECOVERY);
+              url_, SDCH_META_REFRESH_RECOVERY);
+          LogSdchProblem(SDCH_META_REFRESH_RECOVERY);
         }
         decoding_status_ = META_REFRESH_RECOVERY;
         // Issue a meta redirect with SDCH disabled.
@@ -357,7 +406,7 @@
   if (!ret) {
     vcdiff_streaming_decoder_.reset(NULL);  // Don't call it again.
     decoding_status_ = DECODING_ERROR;
-    SdchManager::SdchErrorRecovery(SdchManager::DECODE_BODY_ERROR);
+    LogSdchProblem(SDCH_DECODE_BODY_ERROR);
     return FILTER_ERROR;
   }
 
@@ -394,32 +443,35 @@
   DCHECK(!dictionary_.get());
   dictionary_hash_is_plausible_ = true;  // Assume plausible, but check.
 
+  SdchProblemCode rv = SDCH_OK;
   if ('\0' == dictionary_hash_[kServerIdLength - 1]) {
     SdchManager* manager(url_request_context_->sdch_manager());
-    manager->GetVcdiffDictionary(
-        std::string(dictionary_hash_, 0, kServerIdLength - 1),
-        url_, &dictionary_);
-  } else {
-    dictionary_hash_is_plausible_ = false;
-  }
-
-  if (!dictionary_.get()) {
-    DCHECK(dictionary_hash_.size() == kServerIdLength);
-    // Since dictionary was not found, check to see if hash was even plausible.
-    for (size_t i = 0; i < kServerIdLength - 1; ++i) {
-      char base64_char = dictionary_hash_[i];
-      if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) {
-        dictionary_hash_is_plausible_ = false;
-        break;
+    rv = manager->GetVcdiffDictionary(
+        std::string(dictionary_hash_, 0, kServerIdLength - 1), url_,
+        &dictionary_);
+    if (rv == SDCH_DICTIONARY_HASH_NOT_FOUND) {
+      DCHECK(dictionary_hash_.size() == kServerIdLength);
+      // Since dictionary was not found, check to see if hash was even
+      // plausible.
+      for (size_t i = 0; i < kServerIdLength - 1; ++i) {
+        char base64_char = dictionary_hash_[i];
+        if (!isalnum(base64_char) && '-' != base64_char && '_' != base64_char) {
+          rv = SDCH_DICTIONARY_HASH_MALFORMED;
+          dictionary_hash_is_plausible_ = false;
+          break;
+        }
       }
     }
-    if (dictionary_hash_is_plausible_)
-      SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_NOT_FOUND);
-    else
-      SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_HASH_MALFORMED);
+  } else {
+    dictionary_hash_is_plausible_ = false;
+    rv = SDCH_DICTIONARY_HASH_MALFORMED;
+  }
+  if (rv != SDCH_OK) {
+    LogSdchProblem(rv);
     decoding_status_ = DECODING_ERROR;
     return FILTER_ERROR;
   }
+  DCHECK(dictionary_.get());
   vcdiff_streaming_decoder_.reset(new open_vcdiff::VCDiffStreamingDecoder);
   vcdiff_streaming_decoder_->SetAllowVcdTarget(false);
   vcdiff_streaming_decoder_->StartDecoding(dictionary_->text().data(),
@@ -446,4 +498,11 @@
   return amount;
 }
 
+void SdchFilter::LogSdchProblem(SdchProblemCode problem) {
+  SdchManager::SdchErrorRecovery(problem);
+  filter_context_.GetNetLog().AddEvent(
+      NetLog::TYPE_SDCH_DECODING_ERROR,
+      base::Bind(&NetLogSdchResourceProblemCallback, problem));
+}
+
 }  // namespace net
diff --git a/net/filter/sdch_filter.h b/net/filter/sdch_filter.h
index e9648b1..a1a6607 100644
--- a/net/filter/sdch_filter.h
+++ b/net/filter/sdch_filter.h
@@ -64,6 +64,9 @@
   // specified dest_buffer.
   int OutputBufferExcess(char* const dest_buffer, size_t available_space);
 
+  // Add SDCH Problem to net-log and record histogram.
+  void LogSdchProblem(SdchProblemCode problem);
+
   // Context data from the owner of this filter.
   const FilterContext& filter_context_;
 
diff --git a/net/filter/sdch_filter_unittest.cc b/net/filter/sdch_filter_unittest.cc
index 2263001..79b5673 100644
--- a/net/filter/sdch_filter_unittest.cc
+++ b/net/filter/sdch_filter_unittest.cc
@@ -67,14 +67,7 @@
   // the attempt succeeded.
   bool AddSdchDictionary(const std::string& dictionary_text,
                          const GURL& gurl) {
-    std::string list;
-    sdch_manager_->GetAvailDictionaryList(gurl, &list);
-    sdch_manager_->AddSdchDictionary(dictionary_text, gurl);
-    std::string list2;
-    sdch_manager_->GetAvailDictionaryList(gurl, &list2);
-
-    // The list of hashes should change iff the addition succeeds.
-    return (list != list2);
+    return sdch_manager_->AddSdchDictionary(dictionary_text, gurl) == SDCH_OK;
   }
 
   MockFilterContext* filter_context() { return filter_context_.get(); }
@@ -412,9 +405,10 @@
   EXPECT_EQ(0, output_bytes_or_buffer_size);
   EXPECT_EQ(Filter::FILTER_ERROR, status);
 
-  EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager_->IsInSupportedDomain(GURL(url_string)));
   sdch_manager_->ClearBlacklistings();
-  EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_OK, sdch_manager_->IsInSupportedDomain(GURL(url_string)));
 }
 
 TEST_F(SdchFilterTest, DictionaryAddOnce) {
@@ -667,10 +661,11 @@
                               filter.get(), &output));
   EXPECT_EQ(output.size(), 0u);  // No output written.
 
-  EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
-  EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(wrong_domain_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager_->IsInSupportedDomain(wrong_domain_url));
   sdch_manager_->ClearBlacklistings();
-  EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(wrong_domain_url));
+  EXPECT_EQ(SDCH_OK, sdch_manager_->IsInSupportedDomain(wrong_domain_url));
 }
 
 TEST_F(SdchFilterTest, DictionaryPathValidation) {
@@ -723,9 +718,10 @@
                               output_block_size, filter.get(), &output));
   EXPECT_EQ(output.size(), 0u);  // No output written.
 
-  EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager_->IsInSupportedDomain(GURL(url_string)));
   sdch_manager_->ClearBlacklistings();
-  EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_OK, sdch_manager_->IsInSupportedDomain(GURL(url_string)));
 }
 
 TEST_F(SdchFilterTest, DictionaryPortValidation) {
@@ -789,9 +785,10 @@
                               output_block_size, filter.get(), &output));
   EXPECT_EQ(output.size(), 0u);  // No output written.
 
-  EXPECT_FALSE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_DOMAIN_BLACKLIST_INCLUDES_TARGET,
+            sdch_manager_->IsInSupportedDomain(GURL(url_string)));
   sdch_manager_->ClearBlacklistings();
-  EXPECT_TRUE(sdch_manager_->IsInSupportedDomain(GURL(url_string)));
+  EXPECT_EQ(SDCH_OK, sdch_manager_->IsInSupportedDomain(GURL(url_string)));
 }
 
 //------------------------------------------------------------------------------
diff --git a/net/http/transport_security_state_static.certs b/net/http/transport_security_state_static.certs
index 525d05b..04f4ae4 100644
--- a/net/http/transport_security_state_static.certs
+++ b/net/http/transport_security_state_static.certs
@@ -1507,3 +1507,9 @@
 
 FacebookBackup
 sha1/1ww8E0AYsR2oX5lndk2hwp2Uosk=
+
+SpiderOak1
+sha1/UPrvFUSrp9aal5v6Rn0Jv3YJ/wU=
+
+SpiderOak2
+sha1/D0fS/hquA6QprluciyO1hlFUAxg=
diff --git a/net/http/transport_security_state_static.h b/net/http/transport_security_state_static.h
index 867cafd..1774a24 100644
--- a/net/http/transport_security_state_static.h
+++ b/net/http/transport_security_state_static.h
@@ -263,6 +263,7 @@
   DOMAIN_YOUTUBE_NOCOOKIE_COM,
   DOMAIN_2MDN_NET,
   DOMAIN_FACEBOOK_COM,
+  DOMAIN_SPIDEROAK_COM,
   // Boundary value for UMA_HISTOGRAM_ENUMERATION.
   DOMAIN_NUM_EVENTS,
 };
@@ -530,6 +531,14 @@
     "\xd7\x0c\x3c\x13\x40\x18\xb1\x1d\xa8\x5f"
     "\x99\x67\x76\x4d\xa1\xc2\x9d\x94\xa2\xc9";
 
+static const char kSPKIHash_SpiderOak1[] =
+    "\x50\xfa\xef\x15\x44\xab\xa7\xd6\x9a\x97"
+    "\x9b\xfa\x46\x7d\x09\xbf\x76\x09\xff\x05";
+
+static const char kSPKIHash_SpiderOak2[] =
+    "\x0f\x47\xd2\xfe\x1a\xae\x03\xa4\x29\xae"
+    "\x5b\x9c\x8b\x23\xb5\x86\x51\x54\x03\x18";
+
 // The following is static data describing the hosts that are hardcoded with
 // certificate pins or HSTS information.
 
@@ -668,6 +677,12 @@
   kSPKIHash_FacebookBackup,
   NULL,
 };
+static const char* const kSpideroakAcceptableCerts[] = {
+  kSPKIHash_RapidSSL,
+  kSPKIHash_SpiderOak1,
+  kSPKIHash_SpiderOak2,
+  NULL,
+};
 
 struct Pinset {
   const char *const *const accepted_pins;
@@ -685,6 +700,7 @@
   {kLavabitAcceptableCerts, kNoRejectedPublicKeys},
   {kDropboxAcceptableCerts, kNoRejectedPublicKeys},
   {kFacebookAcceptableCerts, kNoRejectedPublicKeys},
+  {kSpideroakAcceptableCerts, kNoRejectedPublicKeys},
 };
 
 // kHSTSHuffmanTree describes a Huffman tree. The nodes of the tree are pairs
@@ -1441,805 +1457,805 @@
   0x04, 0x27, 0x45, 0x4d, 0xc0, 0x48, 0xa7, 0xea,
   0xfa, 0xdd, 0x96, 0x29, 0xc6, 0x86, 0x70, 0x42,
   0x12, 0xa7, 0x9f, 0x7c, 0x42, 0x9c, 0x5e, 0x4f,
-  0xb3, 0x6f, 0x02, 0xa7, 0x4b, 0x84, 0xf5, 0xfe,
-  0x5f, 0x3f, 0x7e, 0x9a, 0xb5, 0x97, 0x3a, 0x7f,
-  0xfb, 0xf7, 0x6b, 0x07, 0x39, 0x8b, 0x6f, 0x6c,
-  0x74, 0xfa, 0x8d, 0xdf, 0xb2, 0x93, 0xa7, 0xde,
-  0xaa, 0xd0, 0xc3, 0xe5, 0xfb, 0x3e, 0x5e, 0x10,
-  0x6a, 0x7c, 0xbf, 0x66, 0xe7, 0x9f, 0x2f, 0xd9,
-  0xed, 0x5f, 0x95, 0x3e, 0x5f, 0xb1, 0xb1, 0xe8,
-  0xfc, 0x8a, 0x7c, 0xb9, 0x5c, 0xf9, 0xf2, 0xfd,
-  0x83, 0xe5, 0xfb, 0x37, 0x5c, 0xf9, 0x7e, 0xb0,
-  0xb7, 0x93, 0xfe, 0x7f, 0x5a, 0xa4, 0xcf, 0x66,
-  0xe7, 0x80, 0x7c, 0xbf, 0x60, 0xf9, 0x7e, 0xcc,
-  0x05, 0x3e, 0x5f, 0xb3, 0xfd, 0x80, 0xe1, 0xc6,
-  0xd9, 0xb1, 0xf2, 0xfd, 0x9f, 0xb2, 0xde, 0xae,
-  0xb4, 0x1f, 0x2f, 0xd8, 0x02, 0x28, 0xfe, 0x45,
-  0x54, 0x59, 0xe1, 0xa1, 0x6e, 0x7c, 0xbf, 0x60,
-  0xf9, 0x7e, 0xe1, 0xae, 0x98, 0x21, 0x3e, 0x5f,
-  0xb0, 0xf5, 0x62, 0x3b, 0x1a, 0xe4, 0x21, 0x29,
-  0x84, 0xe8, 0x94, 0xb0, 0xc6, 0xb0, 0xba, 0xba,
-  0xf0, 0x49, 0xa7, 0xb1, 0xeb, 0xa4, 0xb9, 0x7e,
-  0xdc, 0x88, 0xf9, 0xff, 0x62, 0x6d, 0x82, 0x1e,
-  0xb3, 0x47, 0x4c, 0xfa, 0x0a, 0x8a, 0x11, 0x2d,
-  0x4a, 0x17, 0xcf, 0x60, 0x57, 0x25, 0x7a, 0x71,
-  0x8e, 0x7f, 0xfe, 0xa5, 0xe2, 0xad, 0xb9, 0xa5,
-  0xda, 0xca, 0xce, 0x68, 0xe8, 0x55, 0xdc, 0x3c,
-  0x26, 0xf1, 0x7f, 0x4e, 0x72, 0x6a, 0x59, 0x3f,
-  0xed, 0x2b, 0x4f, 0xd6, 0xd6, 0xd5, 0x0e, 0x9f,
-  0xbf, 0xda, 0x6d, 0xcf, 0x3a, 0x70, 0x42, 0x12,
-  0xa7, 0x6f, 0x50, 0x14, 0xe2, 0xf2, 0x7f, 0xdf,
-  0xe7, 0xef, 0x1c, 0x6d, 0xc2, 0x74, 0xff, 0x7f,
-  0x81, 0xa1, 0xea, 0x0a, 0x4e, 0x8d, 0x93, 0x31,
-  0x62, 0x08, 0x12, 0xbe, 0x59, 0x73, 0xf9, 0xff,
-  0x7f, 0xfe, 0xd5, 0xbb, 0xae, 0xe2, 0xdc, 0xe9,
-  0xc1, 0x08, 0x4b, 0x10, 0x82, 0x7c, 0x29, 0xdc,
-  0x85, 0x88, 0x40, 0xe3, 0x55, 0x38, 0x21, 0x09,
-  0x62, 0x0f, 0x41, 0x62, 0x0f, 0x38, 0xd5, 0x4c,
-  0xac, 0xc4, 0x49, 0xa3, 0x5c, 0xfa, 0xeb, 0x75,
-  0x61, 0xd3, 0xdf, 0xf2, 0xe9, 0x3a, 0x76, 0xf5,
-  0x01, 0xd1, 0x41, 0xe0, 0x30, 0x8e, 0x7c, 0x8b,
-  0x65, 0x61, 0x53, 0xef, 0xf7, 0xff, 0x85, 0x4d,
-  0x88, 0x54, 0xc1, 0x09, 0x51, 0x87, 0xeb, 0x52,
-  0x5b, 0x93, 0x04, 0x52, 0x7f, 0x7f, 0x7a, 0x82,
-  0xd8, 0xde, 0x53, 0x8d, 0xdc, 0x2a, 0x70, 0x1e,
-  0x66, 0xe8, 0x69, 0xcf, 0xfe, 0xb2, 0x82, 0xb9,
-  0x9b, 0x77, 0xfb, 0x49, 0xd3, 0xfa, 0xbb, 0xd9,
-  0x50, 0xf5, 0x27, 0x42, 0xab, 0xb1, 0xc4, 0xcf,
-  0x46, 0x0a, 0x31, 0xd6, 0x71, 0xa5, 0x52, 0xa7,
-  0x04, 0x21, 0x2a, 0x7c, 0xf0, 0x77, 0xf6, 0x29,
-  0xc5, 0xe4, 0xff, 0xf7, 0xe9, 0xd1, 0x48, 0x17,
-  0xe9, 0xd4, 0x7f, 0x8e, 0x9f, 0xfe, 0xc5, 0x76,
-  0xdf, 0x5d, 0x53, 0x34, 0xf8, 0x4e, 0x9e, 0x6f,
-  0xb0, 0x1b, 0x1d, 0x0f, 0x3f, 0x7e, 0x50, 0x9f,
-  0xfc, 0xfc, 0x10, 0x33, 0xd5, 0xdf, 0x55, 0xc3,
-  0xa7, 0xbd, 0xb6, 0x30, 0xe8, 0x54, 0xe3, 0x9e,
-  0x6f, 0xd0, 0xca, 0xf9, 0x0e, 0xa9, 0x53, 0xf6,
-  0xee, 0xbe, 0xfd, 0x2f, 0x3a, 0x7f, 0xdc, 0x3b,
-  0x9e, 0xb6, 0x75, 0x20, 0x3a, 0x7f, 0xd5, 0xaa,
-  0x8d, 0xd5, 0xdb, 0x78, 0xe9, 0xff, 0x7f, 0x9a,
-  0xb7, 0x08, 0xfb, 0x63, 0xa3, 0x11, 0xde, 0x86,
-  0x7e, 0x40, 0x61, 0xf4, 0xf3, 0xf7, 0xe3, 0x47,
-  0x4f, 0x87, 0x6c, 0xcf, 0x9d, 0x3f, 0xf6, 0xef,
-  0xd9, 0x65, 0x6d, 0x5b, 0x2d, 0x27, 0x47, 0x1f,
-  0x85, 0x49, 0xa7, 0xff, 0xb2, 0xf5, 0xc6, 0xac,
-  0xad, 0xb2, 0xd6, 0x53, 0xa7, 0xf5, 0xdb, 0xab,
-  0x5f, 0x6e, 0x94, 0x6a, 0x74, 0x6c, 0x8b, 0x4f,
-  0x90, 0xdd, 0x42, 0x7f, 0xfb, 0xd5, 0xcd, 0xaf,
-  0x5f, 0x69, 0xb7, 0x7f, 0xc7, 0x4f, 0xff, 0xef,
-  0xdf, 0x2d, 0xe5, 0xbf, 0x80, 0xaf, 0x70, 0x42,
-  0x12, 0xa7, 0xb6, 0xcc, 0xd2, 0x54, 0xe7, 0xff,
-  0x53, 0x44, 0x33, 0x38, 0x21, 0x09, 0x53, 0xb3,
-  0xe8, 0x53, 0x8b, 0xc9, 0xff, 0x65, 0x19, 0xb7,
-  0x3f, 0xeb, 0x41, 0xd0, 0x03, 0xe8, 0xf9, 0x4c,
-  0xfe, 0x7f, 0xf2, 0xf7, 0xd6, 0x83, 0xa1, 0x53,
-  0x89, 0xa1, 0x86, 0x92, 0x31, 0x85, 0x77, 0x11,
-  0x4f, 0x7a, 0xfe, 0x53, 0xa7, 0xf6, 0xb8, 0x20,
-  0x07, 0xbe, 0x74, 0xff, 0xf9, 0x5f, 0xed, 0xad,
-  0xbe, 0xb8, 0x29, 0xdc, 0x86, 0x88, 0x32, 0x2c,
-  0x89, 0x4b, 0x99, 0xcf, 0xaa, 0x3e, 0x0e, 0xec,
-  0xe9, 0xfd, 0xb9, 0x95, 0xdc, 0xc1, 0x53, 0xa1,
-  0xe9, 0x9c, 0xfa, 0x16, 0xb5, 0x23, 0xb9, 0x5c,
-  0xff, 0xf2, 0xfe, 0x8d, 0x0d, 0x7b, 0xf9, 0xb6,
-  0x7f, 0x49, 0xd3, 0x94, 0x5a, 0x3a, 0x15, 0x77,
-  0x33, 0x63, 0xbc, 0x8d, 0x21, 0x0c, 0x7d, 0x1e,
-  0xe7, 0x47, 0x11, 0xaa, 0x1e, 0xe2, 0xb4, 0xff,
-  0xf2, 0x2d, 0x6a, 0xac, 0xcb, 0xfa, 0xb6, 0xe3,
-  0xa7, 0xf7, 0xfe, 0xaf, 0x62, 0xf8, 0xe9, 0xfd,
-  0x7f, 0x36, 0xf5, 0xde, 0xa5, 0x49, 0x87, 0x4f,
-  0xd9, 0xfd, 0x22, 0xae, 0xf1, 0xe2, 0xef, 0x35,
-  0x8c, 0x4c, 0x2f, 0xc9, 0xb5, 0x77, 0x9e, 0x1d,
-  0x69, 0x79, 0xd3, 0xfb, 0xef, 0xfe, 0x31, 0x50,
-  0xe9, 0xcc, 0xdb, 0x0e, 0x85, 0x3f, 0x0c, 0x23,
-  0xe3, 0x19, 0xd7, 0xf5, 0x07, 0x4f, 0xfb, 0x5b,
-  0xd7, 0x78, 0x81, 0x9e, 0xa9, 0xd3, 0xff, 0x2f,
-  0xfa, 0xca, 0x07, 0x0d, 0x6a, 0x54, 0x6c, 0x88,
-  0x46, 0x21, 0x4f, 0xad, 0xef, 0x53, 0x53, 0xa0,
-  0xa9, 0xfa, 0xbb, 0xd4, 0x55, 0x85, 0x41, 0x50,
-  0x54, 0x15, 0x05, 0x43, 0xcf, 0x7f, 0xc1, 0x40,
-  0x2d, 0xd4, 0x2b, 0x70, 0x29, 0xbc, 0x2a, 0x6b,
-  0x61, 0x53, 0xf7, 0x75, 0xda, 0x56, 0x15, 0xa0,
-  0xb5, 0x93, 0x76, 0x54, 0x15, 0x05, 0x43, 0xcb,
-  0x4f, 0x05, 0x41, 0x50, 0x54, 0x15, 0x05, 0x41,
-  0x50, 0x54, 0x50, 0x6f, 0x36, 0x0a, 0xf0, 0x50,
-  0x02, 0xaa, 0x14, 0xd8, 0x2a, 0x0a, 0x82, 0xa1,
-  0xe5, 0xa5, 0x42, 0xa0, 0xa8, 0x2a, 0x0a, 0x82,
-  0xa1, 0xe6, 0xa0, 0x01, 0x57, 0x0a, 0x6f, 0x0a,
-  0x82, 0xa0, 0xa8, 0x2a, 0x0a, 0x8a, 0x0d, 0x46,
-  0x90, 0xa1, 0x0a, 0xb0, 0x54, 0xb4, 0x95, 0x05,
-  0x41, 0x50, 0x54, 0x15, 0x1b, 0x1a, 0x8a, 0x42,
-  0x80, 0x15, 0xa8, 0x54, 0x15, 0x05, 0x41, 0x53,
-  0xeb, 0x28, 0x2b, 0x85, 0x41, 0x50, 0xf3, 0xce,
-  0x40, 0xab, 0x05, 0x70, 0x50, 0x09, 0xa4, 0x85,
-  0x41, 0x50, 0x54, 0x15, 0x05, 0x43, 0xcd, 0x45,
-  0x21, 0x5e, 0x0a, 0x6c, 0x15, 0x05, 0x41, 0x50,
-  0x54, 0x15, 0x0f, 0x35, 0x1b, 0x05, 0x58, 0x2b,
-  0xe1, 0x52, 0xb1, 0x50, 0x54, 0x15, 0x27, 0x95,
-  0x05, 0x52, 0x58, 0x41, 0x50, 0x54, 0x15, 0x05,
-  0x45, 0x07, 0xcc, 0xf0, 0xad, 0x23, 0x48, 0x34,
-  0xd0, 0x50, 0x02, 0xae, 0x15, 0x2c, 0x2a, 0x0a,
-  0x82, 0xa4, 0xf2, 0xa0, 0xaa, 0x4b, 0x08, 0x2a,
-  0x0a, 0x85, 0x3d, 0x27, 0x85, 0x78, 0x68, 0x46,
-  0x98, 0x15, 0x05, 0x41, 0x50, 0x54, 0x15, 0x05,
-  0x42, 0x9b, 0x2a, 0x42, 0x84, 0x29, 0x81, 0x5f,
-  0x0a, 0x82, 0xa0, 0xa8, 0x2a, 0x04, 0xbe, 0xa8,
-  0x55, 0xc2, 0xa0, 0xa8, 0x2a, 0x0a, 0x86, 0x17,
-  0xdf, 0x0a, 0xb8, 0x54, 0x98, 0x54, 0x15, 0x05,
-  0x40, 0x0b, 0x4d, 0x42, 0xa0, 0xa8, 0x2a, 0x0a,
-  0x82, 0xa1, 0x4d, 0x43, 0x41, 0x56, 0x0a, 0xd4,
-  0x2a, 0x15, 0x7e, 0xb6, 0x87, 0x27, 0x9e, 0xec,
-  0x53, 0x8b, 0x88, 0xdb, 0x4a, 0x47, 0x99, 0xb7,
-  0x67, 0xad, 0x1d, 0x0c, 0x23, 0x18, 0x8f, 0x63,
-  0x7e, 0x66, 0x01, 0xe7, 0xdd, 0xaa, 0xcd, 0x76,
-  0x1d, 0x5e, 0x5b, 0x32, 0x85, 0x2b, 0x70, 0xb7,
-  0x79, 0x23, 0x7a, 0x4c, 0xf9, 0xff, 0x5c, 0xa9,
-  0x4e, 0x4d, 0x5e, 0x77, 0x95, 0x85, 0x4f, 0x79,
-  0x38, 0x4e, 0x9d, 0xed, 0xb0, 0xe9, 0xcb, 0xbd,
-  0xd4, 0xa2, 0x3c, 0x4e, 0x6c, 0x37, 0x71, 0xf9,
-  0xfd, 0x6f, 0x07, 0x61, 0x5a, 0x0e, 0x8a, 0x51,
-  0x08, 0xd2, 0x84, 0xc0, 0x53, 0xa7, 0xe1, 0xef,
-  0xef, 0x50, 0x1d, 0x37, 0x09, 0xd2, 0xf1, 0xc8,
-  0x5a, 0x49, 0x0e, 0x93, 0x0e, 0x9d, 0x9b, 0x8e,
-  0xf2, 0x24, 0xc4, 0x56, 0xc8, 0x3c, 0x3d, 0xbc,
-  0x3e, 0x7f, 0xfd, 0xaa, 0xe8, 0xe1, 0x1e, 0x02,
-  0xb8, 0x21, 0x09, 0xd0, 0xf6, 0x6c, 0xde, 0xd0,
-  0xa0, 0x42, 0xcf, 0x42, 0x85, 0xa2, 0x4e, 0xa5,
-  0x4f, 0xfe, 0x17, 0x17, 0x5e, 0x9f, 0xcb, 0xfb,
-  0xf7, 0xf5, 0xc3, 0xa7, 0xe7, 0xff, 0xcf, 0xb6,
-  0x1d, 0x3e, 0xa3, 0xc2, 0xaf, 0x3a, 0x04, 0xf5,
-  0x3e, 0x5b, 0x3f, 0xeb, 0x28, 0x83, 0xf8, 0x1e,
-  0x01, 0xd3, 0xb3, 0x1a, 0x3a, 0x59, 0x63, 0xd7,
-  0x01, 0xe4, 0xf3, 0x17, 0x28, 0x3a, 0x7d, 0x8d,
-  0xbe, 0xb4, 0x9d, 0x1e, 0x3c, 0xaa, 0x90, 0xcf,
-  0x2f, 0xee, 0x87, 0x49, 0x71, 0x32, 0xbf, 0xbc,
-  0x5d, 0xc7, 0x70, 0x8a, 0x7b, 0x5e, 0x17, 0x9d,
-  0x3c, 0xba, 0xb7, 0x75, 0x2a, 0x7c, 0xf7, 0x04,
-  0x21, 0x3a, 0x3e, 0x79, 0xfa, 0x93, 0xc6, 0xc8,
-  0x93, 0xc7, 0x08, 0x62, 0xaa, 0xc0, 0x47, 0x63,
-  0xac, 0x36, 0x27, 0xe1, 0xd4, 0x19, 0xf4, 0x3a,
-  0x7f, 0xa8, 0xfe, 0x3e, 0xd8, 0x0a, 0x9d, 0x3d,
-  0xb6, 0xca, 0xd8, 0xe9, 0xff, 0xf2, 0xd9, 0x58,
-  0x8b, 0x7c, 0x14, 0xee, 0x43, 0x45, 0xf1, 0x3f,
-  0x83, 0xd7, 0xaa, 0xe5, 0x07, 0x4f, 0xff, 0xd9,
-  0x7d, 0xef, 0x56, 0xde, 0xf8, 0x07, 0xca, 0xcc,
-  0x2a, 0x6b, 0xe1, 0xd3, 0xe1, 0xf5, 0x1c, 0xc3,
-  0x4c, 0x27, 0x3d, 0x7d, 0x57, 0x8d, 0x30, 0x9c,
-  0xc0, 0x53, 0x50, 0x27, 0x3f, 0xbf, 0xda, 0x6e,
-  0xa2, 0x03, 0x50, 0x27, 0x3f, 0xab, 0x96, 0xf5,
-  0x75, 0xa0, 0xd3, 0x09, 0xcd, 0x9b, 0x1a, 0x61,
-  0x39, 0x82, 0x13, 0xcc, 0x27, 0x18, 0x9a, 0x65,
-  0x26, 0x9e, 0x2e, 0x61, 0x15, 0x50, 0x1b, 0x21,
-  0x04, 0x8e, 0x57, 0x2c, 0xc2, 0x67, 0x1f, 0x3c,
-  0xbd, 0x4a, 0x7e, 0xe1, 0x8f, 0x22, 0x2a, 0xaa,
-  0x16, 0xf2, 0x95, 0x21, 0x55, 0xce, 0x6c, 0x72,
-  0x84, 0xb6, 0x5b, 0xbc, 0xab, 0x79, 0xf6, 0xd8,
-  0x3e, 0xd2, 0x74, 0xfb, 0xf9, 0xbf, 0x1a, 0x3a,
-  0x7f, 0xad, 0xcc, 0xb7, 0x96, 0x97, 0x9d, 0x3f,
-  0x6f, 0xfb, 0xf7, 0x3a, 0x83, 0xa3, 0xc7, 0xd8,
-  0x03, 0x98, 0xfa, 0x2d, 0xef, 0x09, 0x58, 0x55,
-  0xd2, 0x2c, 0x97, 0x91, 0xe5, 0x2e, 0x87, 0x04,
-  0xff, 0xe6, 0x5e, 0xbe, 0xfd, 0x2f, 0xbf, 0xab,
-  0xe3, 0xa7, 0xff, 0xf7, 0xf2, 0x9c, 0xaf, 0x7e,
-  0xde, 0x5b, 0xdb, 0x5e, 0x61, 0xd3, 0xf7, 0xf5,
-  0x67, 0xac, 0xa7, 0x4f, 0xff, 0xbb, 0xf7, 0xee,
-  0xb7, 0xd6, 0xf5, 0x0e, 0x58, 0xe9, 0xc3, 0x5a,
-  0x9e, 0x20, 0x39, 0xff, 0xed, 0xe2, 0xb6, 0x5d,
-  0x18, 0x29, 0xdc, 0x86, 0x88, 0x0d, 0xc6, 0xa2,
-  0x00, 0x8e, 0x5b, 0xbd, 0xc6, 0x26, 0x6d, 0xe8,
-  0xc4, 0xe7, 0xff, 0xf7, 0x3f, 0x2b, 0xe1, 0x1f,
-  0x33, 0x7d, 0xed, 0x81, 0xb9, 0xd3, 0xff, 0xfd,
-  0xcf, 0xcf, 0xb4, 0xfc, 0xa5, 0xfb, 0xd4, 0x0e,
-  0x08, 0x42, 0x54, 0x59, 0x19, 0x7f, 0x61, 0x9f,
-  0xcb, 0x82, 0x9d, 0xc8, 0x68, 0x82, 0x67, 0xf9,
-  0x6f, 0x82, 0x9d, 0xc8, 0x68, 0xbe, 0x67, 0xde,
-  0x6d, 0xfc, 0xae, 0xc7, 0xf4, 0x87, 0x53, 0xfe,
-  0xa3, 0xa9, 0xdc, 0xcb, 0xff, 0x9b, 0x1d, 0x38,
-  0x21, 0x09, 0x53, 0xf5, 0xed, 0x89, 0xc2, 0x53,
-  0x8b, 0xc8, 0xa1, 0x13, 0x3f, 0x60, 0x9f, 0xfa,
-  0x86, 0x2d, 0x35, 0xfe, 0x51, 0xbd, 0xe7, 0x4f,
-  0xff, 0x6f, 0xa7, 0xfa, 0x12, 0xde, 0x00, 0x14,
-  0x5e, 0x74, 0xe0, 0x84, 0x25, 0x4f, 0xed, 0xe0,
-  0x5f, 0xe5, 0x37, 0x29, 0xc5, 0xe4, 0xff, 0xfc,
-  0xdd, 0xe8, 0x4b, 0x7b, 0x6d, 0xb0, 0x3a, 0x2f,
-  0x5c, 0xa0, 0xe9, 0x75, 0x91, 0x57, 0xaa, 0x24,
-  0x3d, 0x54, 0x5f, 0xa1, 0xb4, 0x24, 0x8c, 0x49,
-  0xbc, 0x63, 0x73, 0xeb, 0x65, 0xda, 0x79, 0xd3,
-  0xfe, 0xcb, 0xa8, 0xd6, 0xcb, 0xfb, 0x9e, 0x20,
-  0x89, 0xfc, 0xb8, 0x29, 0xdc, 0x86, 0x88, 0x21,
-  0xc7, 0x93, 0x3f, 0x75, 0x84, 0x7c, 0x13, 0xa7,
-  0xed, 0xde, 0xc1, 0xef, 0xbc, 0xe8, 0xf9, 0xee,
-  0xea, 0x57, 0x16, 0x4c, 0xf0, 0x0e, 0x3f, 0x85,
-  0x44, 0xff, 0x2f, 0xef, 0xbf, 0x2d, 0xd4, 0x9d,
-  0x3f, 0xfd, 0xc1, 0xbe, 0x59, 0x7d, 0x7f, 0xe5,
-  0xbc, 0x74, 0x3d, 0x11, 0x1f, 0x3a, 0x9f, 0xd7,
-  0xde, 0xca, 0x87, 0xa9, 0x3a, 0x7b, 0xcd, 0x78,
-  0x27, 0x4f, 0xff, 0xb5, 0xa3, 0xeb, 0x96, 0x72,
-  0xdf, 0x2d, 0xa8, 0x9d, 0x3e, 0xcb, 0xd7, 0x7d,
-  0x76, 0x3f, 0x9d, 0xe4, 0x73, 0xf2, 0x5b, 0xdb,
-  0x9e, 0xd2, 0x74, 0xfc, 0xc5, 0xdd, 0xdb, 0x28,
-  0x3a, 0x7f, 0xff, 0xfb, 0xd7, 0xe6, 0x77, 0xc0,
-  0xff, 0x57, 0x56, 0x5b, 0xcb, 0x7b, 0x6b, 0xcc,
-  0x3a, 0x36, 0x47, 0x1f, 0x8c, 0xb8, 0xc6, 0x70,
-  0xef, 0xa9, 0xd3, 0xfe, 0xef, 0xa6, 0x0a, 0x77,
-  0x21, 0xa2, 0x11, 0x85, 0x3e, 0x2d, 0x47, 0x67,
-  0xff, 0x2e, 0x53, 0xbe, 0xfe, 0xfe, 0xaf, 0xca,
-  0x9d, 0x3f, 0xfd, 0xdd, 0x46, 0xfc, 0xb7, 0x31,
-  0xc1, 0x08, 0x4e, 0x96, 0x6c, 0x89, 0xe6, 0x93,
-  0x67, 0x04, 0x21, 0x2a, 0x7f, 0xb0, 0x1c, 0x38,
-  0xdb, 0x36, 0x29, 0xc5, 0xe4, 0xc1, 0x09, 0x53,
-  0x82, 0x10, 0x95, 0x3f, 0x75, 0x1b, 0x59, 0x6a,
-  0x53, 0x8b, 0xc8, 0xfa, 0x2d, 0x82, 0x8f, 0xb8,
-  0x65, 0x3e, 0x4f, 0x6d, 0xbd, 0x85, 0x38, 0xd9,
-  0xce, 0x08, 0x42, 0x54, 0xea, 0xa8, 0x94, 0xe2,
-  0xf2, 0x40, 0xf1, 0xff, 0xdd, 0x5a, 0x7e, 0xdb,
-  0xea, 0xfe, 0x43, 0xa7, 0xf6, 0xf1, 0xdb, 0xcd,
-  0x97, 0x63, 0xa7, 0xf5, 0xed, 0x8d, 0xb2, 0xf5,
-  0x3a, 0x05, 0x13, 0x16, 0x2c, 0xf9, 0xc4, 0x2a,
-  0x3b, 0xf2, 0x18, 0x13, 0xa9, 0xdd, 0x73, 0x75,
-  0x3a, 0x7f, 0xf6, 0x6e, 0xfb, 0xe0, 0xc4, 0x5b,
-  0x2b, 0x0e, 0x9f, 0x93, 0xd5, 0xb7, 0x9a, 0x2a,
-  0x7f, 0x7f, 0x29, 0x7d, 0x7d, 0xa4, 0xe9, 0xee,
-  0xe1, 0xd2, 0x74, 0x68, 0x3d, 0x7a, 0x0d, 0xa7,
-  0x97, 0x98, 0xd8, 0xa9, 0xc1, 0x08, 0x4a, 0x9f,
-  0xfe, 0xde, 0xa0, 0xcc, 0xfd, 0xed, 0xe5, 0xfd,
-  0x05, 0x38, 0xbc, 0x96, 0x22, 0x27, 0x98, 0x7d,
-  0x0a, 0x9f, 0x23, 0xca, 0xe9, 0x4a, 0xf4, 0x21,
-  0x6d, 0x0c, 0x39, 0xff, 0xf3, 0x31, 0x17, 0xfd,
-  0x7a, 0xed, 0xaf, 0x0b, 0xce, 0x9f, 0x2d, 0xea,
-  0xdb, 0x0e, 0x85, 0x3f, 0xcb, 0xaa, 0x4f, 0xff,
-  0x79, 0xb6, 0x7f, 0x6f, 0xf0, 0x73, 0xfd, 0xa4,
-  0xe9, 0xff, 0xfe, 0xda, 0xde, 0x0e, 0x37, 0xf9,
-  0x9d, 0x7a, 0xea, 0xfc, 0xa6, 0xe7, 0x46, 0x23,
-  0x03, 0x94, 0xe1, 0x5b, 0x21, 0x5a, 0x13, 0x5f,
-  0x1c, 0xbe, 0xd0, 0xf4, 0xc9, 0x65, 0x1e, 0x8e,
-  0x49, 0xa8, 0x5f, 0x09, 0x1b, 0x21, 0x5f, 0x68,
-  0xc9, 0xc1, 0x09, 0x2f, 0xc3, 0x02, 0xb2, 0xa7,
-  0x6f, 0x28, 0x2b, 0x58, 0x68, 0x86, 0x1c, 0x33,
-  0x9b, 0x2f, 0xce, 0x9f, 0xfe, 0xcf, 0xba, 0xfa,
-  0x7d, 0x4d, 0x6d, 0x80, 0xe3, 0xa5, 0x4b, 0xcf,
-  0xbf, 0x61, 0xd9, 0xfa, 0xcd, 0x7a, 0xde, 0x61,
-  0xd3, 0xfe, 0xfa, 0xde, 0xdc, 0x0e, 0xa6, 0xa7,
-  0x4e, 0x6b, 0x51, 0x3a, 0x7f, 0xdd, 0xe1, 0xca,
-  0x5c, 0x10, 0x84, 0xe8, 0xe3, 0xdb, 0xa8, 0xec,
-  0xff, 0xf7, 0xd5, 0xfa, 0x37, 0xdf, 0xdf, 0xd5,
-  0xf9, 0x53, 0xa3, 0x13, 0x3e, 0x42, 0xfb, 0x42,
-  0x64, 0x04, 0x33, 0xf9, 0x7e, 0xff, 0xe6, 0x00,
-  0xe9, 0xfc, 0xfc, 0x1a, 0xfd, 0x68, 0x3a, 0x7f,
-  0xf9, 0x5b, 0x28, 0xbb, 0x7d, 0xff, 0x94, 0x78,
-  0x4f, 0x77, 0xbc, 0xff, 0xf6, 0x5d, 0x7e, 0x99,
-  0x7b, 0x78, 0x40, 0x87, 0x4f, 0xba, 0xb9, 0xfb,
-  0x9d, 0x3a, 0xfd, 0xbb, 0x3a, 0x7f, 0x5e, 0xde,
-  0x70, 0x3b, 0xc7, 0x45, 0x09, 0x91, 0xec, 0xbf,
-  0xf4, 0xcb, 0x93, 0x6a, 0x3f, 0x3f, 0xb5, 0x02,
-  0xdb, 0xdc, 0xf3, 0xa7, 0xff, 0xef, 0xe5, 0x75,
-  0xd1, 0x96, 0xef, 0xe3, 0x4f, 0x5a, 0x4e, 0x9f,
-  0xf6, 0x57, 0x5c, 0x14, 0xee, 0x43, 0x44, 0x0d,
-  0x3e, 0xcb, 0xdb, 0x9f, 0xa1, 0x14, 0xbf, 0x5e,
-  0x9f, 0xff, 0xff, 0xb2, 0xf6, 0xef, 0xe9, 0xd1,
-  0x51, 0xee, 0xbb, 0x6c, 0xdb, 0x46, 0x33, 0xbf,
-  0x4b, 0xcf, 0x10, 0x5c, 0xff, 0xbb, 0xb4, 0xa7,
-  0x6d, 0xa3, 0x48, 0x4f, 0x10, 0x5c, 0xff, 0xd6,
-  0xf5, 0xbc, 0xbf, 0xbe, 0x8d, 0x21, 0x3c, 0x41,
-  0x73, 0xf9, 0x7d, 0xfb, 0xe8, 0xd2, 0x13, 0xc4,
-  0x17, 0x3f, 0x33, 0x36, 0xd1, 0xa4, 0x27, 0x88,
-  0x2e, 0x7f, 0xff, 0xbb, 0xff, 0xf3, 0x34, 0x55,
-  0x2d, 0xe1, 0xf6, 0x9a, 0x30, 0x27, 0x88, 0x2e,
-  0x6a, 0x74, 0x6c, 0x9d, 0x0a, 0x28, 0x0a, 0xb7,
-  0x22, 0x7c, 0xfe, 0x2c, 0xaa, 0x5b, 0xf2, 0x8f,
-  0xa7, 0xb8, 0x41, 0xc7, 0x4f, 0xfd, 0x6f, 0x5b,
-  0xcb, 0xfb, 0xe8, 0xd2, 0x13, 0xc4, 0x17, 0x3f,
-  0xcd, 0x55, 0x3d, 0x46, 0x8d, 0x21, 0x3c, 0x41,
-  0x73, 0xeb, 0xd5, 0x59, 0xa1, 0x11, 0x45, 0xbd,
-  0x5a, 0x7f, 0xf6, 0x84, 0xb7, 0x91, 0x6f, 0x5d,
-  0x1a, 0x42, 0x78, 0x82, 0xe7, 0xff, 0xfe, 0xff,
-  0xfc, 0xcd, 0x1a, 0xe6, 0x8a, 0xa5, 0xbc, 0x3e,
-  0xd3, 0x46, 0x04, 0xf1, 0x05, 0xc6, 0x26, 0x4d,
-  0x4a, 0x1f, 0x2e, 0x4f, 0xf5, 0xbc, 0x3e, 0xd3,
-  0x46, 0x04, 0xf1, 0x05, 0xcf, 0xff, 0x77, 0x52,
-  0xfa, 0xdb, 0xdb, 0x6c, 0xa2, 0xa5, 0x4f, 0xfb,
-  0x1e, 0xfd, 0x6a, 0x3f, 0xa3, 0x70, 0xf1, 0x05,
-  0xc2, 0x23, 0xa0, 0x52, 0x2a, 0xa1, 0x3f, 0xe4,
-  0xf0, 0xdf, 0x81, 0x5d, 0x01, 0x3c, 0x41, 0x73,
-  0xf5, 0xbd, 0x6b, 0x78, 0x06, 0x80, 0x2e, 0x7d,
-  0x80, 0xd1, 0xa4, 0x27, 0x88, 0x2e, 0x6c, 0xba,
-  0x1f, 0x9d, 0x8e, 0xe2, 0x94, 0x75, 0xd6, 0x17,
-  0xf3, 0xf3, 0x33, 0x6d, 0x1a, 0x42, 0x78, 0x82,
-  0xe7, 0xfc, 0x96, 0xf0, 0xfb, 0x4d, 0x18, 0x13,
-  0xc4, 0x17, 0x36, 0x68, 0xe4, 0x46, 0x54, 0xfe,
-  0x7f, 0x6b, 0xe6, 0x77, 0xe9, 0x79, 0xe2, 0x0b,
-  0x9f, 0xf6, 0x79, 0xb6, 0x7f, 0x36, 0xe7, 0x9e,
-  0x20, 0xb6, 0x1e, 0x14, 0x6c, 0xbb, 0x8e, 0x02,
-  0xcf, 0xc7, 0xcf, 0x58, 0xc6, 0x2f, 0x18, 0xce,
-  0xb0, 0xb5, 0x0b, 0x8c, 0xf8, 0x15, 0x00, 0x14,
-  0xd1, 0x05, 0xb9, 0x10, 0x13, 0xfe, 0xc7, 0xdb,
-  0x9e, 0xde, 0xdf, 0xad, 0x07, 0x4f, 0xe1, 0xfe,
-  0x6d, 0x6d, 0x42, 0x74, 0xfa, 0x9b, 0xf0, 0x80,
-  0xe9, 0xfb, 0x28, 0xeb, 0x2e, 0xec, 0xe8, 0xf2,
-  0x22, 0xf8, 0xd3, 0xe4, 0xf3, 0xb8, 0x68, 0x3a,
-  0x60, 0x29, 0xd3, 0xde, 0x56, 0x61, 0xd0, 0x74,
-  0xfd, 0xda, 0x6e, 0xa2, 0x03, 0xa3, 0x63, 0x6f,
-  0xf0, 0xa9, 0xff, 0xfc, 0xbe, 0xdb, 0xeb, 0xaa,
-  0x5f, 0x13, 0x65, 0x4d, 0xec, 0x3a, 0x60, 0x29,
-  0xd3, 0x2e, 0x93, 0xa7, 0xfb, 0x2f, 0x55, 0x66,
-  0xfc, 0x68, 0xe9, 0xfd, 0x5c, 0xb7, 0xab, 0xad,
-  0x07, 0x4c, 0x10, 0x95, 0x3f, 0xdf, 0xc6, 0xdc,
-  0xfa, 0xfb, 0x63, 0xa1, 0x13, 0xf7, 0xf0, 0xd8,
-  0x8a, 0xb1, 0x5e, 0xc4, 0x40, 0x62, 0x6e, 0xc5,
-  0x7e, 0x2f, 0x53, 0xa0, 0x9a, 0xef, 0x16, 0x9c,
-  0x10, 0x84, 0xa9, 0x30, 0xa7, 0x17, 0x93, 0xee,
-  0x6b, 0xb8, 0x4a, 0x72, 0x36, 0x77, 0xc2, 0xea,
-  0x7f, 0x53, 0x75, 0xcb, 0x65, 0x07, 0x42, 0xb6,
-  0x40, 0xf9, 0x1b, 0x46, 0x94, 0x1a, 0x4c, 0x7d,
-  0x1a, 0xa8, 0xa7, 0x5a, 0x1b, 0x1d, 0x49, 0x1e,
-  0xfa, 0x35, 0x61, 0xa3, 0xac, 0xaf, 0xf6, 0xc9,
-  0x73, 0xd8, 0x8b, 0x73, 0xa7, 0xb1, 0x99, 0x73,
-  0xa7, 0xba, 0x8d, 0xef, 0x3a, 0x14, 0xf8, 0xe9,
-  0x1f, 0x6f, 0x20, 0x9f, 0xbf, 0xae, 0xcc, 0xe7,
-  0x9d, 0x3f, 0xfd, 0x4b, 0xfe, 0xba, 0x19, 0xf5,
-  0xd3, 0x7f, 0x50, 0x74, 0xfe, 0xad, 0xdb, 0x67,
-  0xf3, 0x63, 0xa1, 0x51, 0x75, 0xe2, 0xfe, 0x56,
-  0x9d, 0xda, 0x37, 0x9d, 0x3f, 0xfd, 0xf7, 0xe8,
-  0xcd, 0xbd, 0x5a, 0x6f, 0xaf, 0x54, 0xe8, 0xd0,
-  0x7e, 0x98, 0x3f, 0x3f, 0x50, 0xd3, 0xdb, 0x83,
-  0x41, 0xd3, 0x3e, 0x83, 0xa7, 0xd6, 0xcf, 0x3e,
-  0xa7, 0x4f, 0xff, 0x59, 0x77, 0xba, 0xff, 0xe0,
-  0x56, 0xaa, 0x02, 0xa7, 0xf0, 0x30, 0x53, 0xb9,
-  0x0f, 0x10, 0x24, 0x3d, 0x16, 0x7b, 0x13, 0x8a,
-  0x8c, 0xcd, 0xef, 0x3a, 0x7a, 0xf4, 0x77, 0xce,
-  0x9e, 0xa6, 0xbd, 0x73, 0xa2, 0x83, 0xdd, 0xc1,
-  0x9b, 0x11, 0x4f, 0xef, 0xf0, 0x6b, 0x55, 0x01,
-  0xd3, 0x82, 0x10, 0x9f, 0x0f, 0xa9, 0xdd, 0xfd,
-  0x8b, 0x87, 0xd1, 0xc6, 0xa6, 0x36, 0x44, 0xa8,
-  0x16, 0xe7, 0xff, 0xd9, 0xff, 0x69, 0x75, 0x6f,
-  0x6d, 0x79, 0xef, 0x53, 0xa2, 0x83, 0xfc, 0xd2,
-  0x49, 0x1b, 0xa9, 0x57, 0x83, 0xcd, 0x32, 0x19,
-  0x5e, 0x84, 0x6f, 0x46, 0x81, 0x3e, 0xf5, 0xd6,
-  0xf5, 0x2a, 0x79, 0x16, 0xf5, 0x2a, 0x60, 0x84,
-  0xa8, 0x79, 0xee, 0xe1, 0x38, 0x48, 0x26, 0xc0,
-  0x94, 0xe3, 0x5d, 0x3f, 0xfe, 0xcb, 0xaa, 0x66,
-  0x7e, 0xf6, 0xf2, 0xfe, 0x83, 0xa0, 0x07, 0xf0,
-  0x12, 0x59, 0xff, 0xfc, 0xad, 0xbd, 0xf0, 0x68,
-  0xbd, 0x71, 0x2d, 0xdf, 0xbd, 0x4e, 0x9f, 0xcd,
-  0x52, 0xfb, 0x6a, 0xa2, 0x74, 0xe7, 0xf0, 0x9d,
-  0x3e, 0x7e, 0x5f, 0x36, 0x2a, 0x5e, 0x68, 0xf0,
-  0x6e, 0x35, 0x30, 0x14, 0xe9, 0x80, 0xa7, 0x4f,
-  0xdf, 0xd5, 0xf9, 0xf7, 0x78, 0xd5, 0x00, 0x56,
-  0x7f, 0xeb, 0xdb, 0x19, 0xbd, 0x41, 0x94, 0xdc,
-  0xe9, 0xfd, 0x4a, 0x78, 0x77, 0xae, 0xc7, 0x4f,
-  0x01, 0x9c, 0xfa, 0x9f, 0xdd, 0xd1, 0xa7, 0x6e,
-  0x65, 0x27, 0x42, 0x9e, 0xc7, 0x1c, 0xcf, 0x57,
-  0x5a, 0x6e, 0x74, 0xe0, 0x84, 0x25, 0x4f, 0xb3,
-  0x4f, 0xf5, 0xa9, 0x4e, 0x2f, 0x27, 0xd8, 0xe0,
-  0x84, 0x27, 0x42, 0x9f, 0x05, 0xce, 0x67, 0x83,
-  0xdf, 0x79, 0xd3, 0x25, 0x8e, 0x9c, 0x10, 0x84,
-  0xa9, 0xfb, 0xdd, 0xa6, 0xde, 0xb9, 0x4e, 0x2f,
-  0x27, 0xd8, 0x0c, 0xc6, 0x8e, 0x95, 0x74, 0x22,
-  0x54, 0x4c, 0x7e, 0x7d, 0x3d, 0xef, 0xea, 0xfd,
-  0x91, 0xdb, 0x90, 0xb6, 0x85, 0x5c, 0x76, 0x79,
-  0x16, 0x32, 0x69, 0x76, 0x15, 0x3b, 0x46, 0x31,
-  0xc4, 0x15, 0x85, 0x05, 0xe3, 0x0e, 0x9f, 0x95,
-  0x82, 0x3d, 0x73, 0xa7, 0xff, 0xbc, 0xca, 0x5f,
-  0x5d, 0x19, 0xff, 0xe7, 0x80, 0x74, 0x58, 0xff,
-  0x6e, 0x55, 0x27, 0x37, 0x48, 0x43, 0x36, 0x2c,
-  0xae, 0xda, 0x23, 0x23, 0x7c, 0xa4, 0xdd, 0xa5,
-  0x80, 0xe5, 0x6e, 0x95, 0xa6, 0x37, 0x14, 0x8e,
-  0xca, 0x99, 0x54, 0xfe, 0x84, 0xeb, 0x53, 0xce,
-  0x43, 0x3a, 0x6a, 0xc9, 0x41, 0x76, 0x9f, 0x0a,
-  0xea, 0x79, 0x68, 0x25, 0x9c, 0xfe, 0x75, 0x82,
-  0xb5, 0x92, 0xf5, 0xeb, 0x39, 0xfd, 0x63, 0x35,
-  0x6d, 0x0e, 0xc0, 0xc2, 0x8b, 0x72, 0x58, 0x9e,
-  0xf9, 0xdd, 0x96, 0xf8, 0xc3, 0x61, 0xd0, 0x88,
-  0xd3, 0x7e, 0x21, 0xae, 0x27, 0xf3, 0xb0, 0x53,
-  0xb9, 0x0d, 0x17, 0x1c, 0xfe, 0x76, 0x0a, 0x77,
-  0x21, 0xa2, 0xeb, 0x9f, 0xf9, 0xdc, 0xf7, 0x60,
-  0xa7, 0x72, 0x1a, 0x25, 0x18, 0x58, 0x46, 0x14,
-  0x3c, 0xa3, 0x63, 0xbd, 0x27, 0x68, 0x77, 0xe8,
-  0x78, 0x6e, 0xd0, 0x3b, 0x11, 0x24, 0xb5, 0x38,
-  0xb9, 0xdb, 0x79, 0xdc, 0xff, 0xe7, 0x33, 0x9e,
-  0xec, 0x14, 0xee, 0x43, 0x44, 0xb5, 0x3e, 0x14,
-  0xee, 0x43, 0x44, 0x6f, 0x3f, 0xee, 0x7b, 0xb0,
-  0x53, 0xb9, 0x0d, 0x12, 0xfc, 0x9d, 0x87, 0xec,
-  0xc3, 0x09, 0xfc, 0xec, 0x14, 0xee, 0x43, 0x45,
-  0x57, 0x3f, 0xda, 0x73, 0xf9, 0x4d, 0xf9, 0x87,
-  0x4d, 0xb7, 0x8e, 0x9f, 0xb0, 0x53, 0xb9, 0x0d,
-  0x12, 0x04, 0x68, 0x3c, 0xc7, 0x0b, 0xcf, 0xab,
-  0xdf, 0xea, 0x4e, 0x87, 0x9e, 0x5d, 0x24, 0x91,
-  0xa5, 0x1e, 0x9d, 0x0d, 0x19, 0xff, 0xbf, 0x94,
-  0x3b, 0x71, 0x7f, 0xfc, 0xb9, 0xd0, 0xe3, 0xf0,
-  0x12, 0x99, 0xfc, 0xec, 0x14, 0xee, 0x43, 0x45,
-  0x91, 0x3f, 0x9d, 0x82, 0x9d, 0xc8, 0x68, 0xb5,
-  0xe7, 0xf3, 0xb0, 0x53, 0xb9, 0x0d, 0x17, 0x24,
-  0xf8, 0x53, 0xb9, 0x0d, 0x17, 0x64, 0xff, 0xb9,
-  0xee, 0xc1, 0x4e, 0xe4, 0x34, 0x51, 0xd2, 0x76,
-  0x1f, 0xb3, 0x0c, 0x27, 0xc2, 0x9d, 0xc8, 0x68,
-  0xa5, 0x67, 0xff, 0xff, 0xac, 0xb4, 0x2d, 0xbc,
-  0xdb, 0xb6, 0xb7, 0x9c, 0x96, 0xf3, 0x56, 0x5a,
-  0x30, 0xe9, 0xf3, 0x99, 0xcf, 0x76, 0x22, 0xc9,
-  0xa3, 0x08, 0xa1, 0x73, 0xbd, 0xf0, 0xc8, 0xa4,
-  0x9f, 0xd1, 0xcf, 0xb0, 0x84, 0x07, 0x75, 0x3b,
-  0xbc, 0x2c, 0x5b, 0x43, 0x66, 0x7f, 0x9e, 0xec,
-  0x14, 0xee, 0x43, 0x44, 0x71, 0x3f, 0xde, 0x76,
-  0x0a, 0x77, 0x21, 0xa2, 0xb5, 0x93, 0xb9, 0x10,
-  0x57, 0x41, 0x9f, 0xfc, 0xe6, 0x73, 0xdd, 0x82,
-  0x9d, 0xc8, 0x68, 0x96, 0xe6, 0xca, 0x4e, 0x9f,
-  0xdb, 0x63, 0x18, 0xbe, 0xa9, 0xd1, 0x49, 0xe4,
-  0xf8, 0x5a, 0x75, 0xb6, 0x79, 0xd3, 0x9e, 0xc4,
-  0x3a, 0x7f, 0xfe, 0xb7, 0x52, 0x0d, 0xad, 0xcf,
-  0xca, 0xff, 0x5e, 0xde, 0x74, 0x1a, 0x21, 0xb9,
-  0xff, 0x73, 0xdd, 0x82, 0x9d, 0xc8, 0x68, 0x98,
-  0x27, 0x0e, 0xa0, 0x2a, 0x7f, 0x7f, 0x2f, 0x75,
-  0x1a, 0x9d, 0x27, 0x2a, 0x6c, 0x94, 0x11, 0xec,
-  0x3b, 0x83, 0x68, 0xbe, 0xc1, 0x7b, 0xa3, 0x6f,
-  0x1c, 0x9c, 0xcd, 0x44, 0xa9, 0xff, 0x73, 0xdd,
-  0x82, 0x9d, 0xc8, 0x68, 0x98, 0xe4, 0xef, 0x1f,
-  0x13, 0x07, 0x27, 0xe5, 0xae, 0x8b, 0xe5, 0x8e,
-  0x9f, 0xff, 0xfe, 0x7d, 0x6d, 0x9a, 0x86, 0xb6,
-  0xc4, 0xca, 0xe8, 0xca, 0x5f, 0x5f, 0x7f, 0xc7,
-  0x4f, 0x27, 0x72, 0x1a, 0x2b, 0x19, 0xff, 0x6e,
-  0x65, 0xff, 0x9a, 0xaf, 0xee, 0x74, 0x69, 0x4c,
-  0x6e, 0x92, 0xe1, 0x84, 0x0d, 0xca, 0xe7, 0xff,
-  0x2f, 0xef, 0xa7, 0x55, 0xfe, 0x22, 0x89, 0xd3,
-  0xfe, 0xcd, 0xad, 0x95, 0xa5, 0xeb, 0x63, 0xa7,
-  0xfd, 0x9b, 0x0f, 0xb5, 0xa0, 0x15, 0x79, 0xd3,
-  0xff, 0xff, 0x7f, 0x5a, 0x31, 0x34, 0x7f, 0x56,
-  0xfd, 0x19, 0x4b, 0xf3, 0x5f, 0x82, 0xa7, 0x4f,
-  0xed, 0xd5, 0x43, 0x4f, 0x6e, 0x0d, 0x07, 0x4e,
-  0xb7, 0x9d, 0x89, 0xe6, 0x22, 0x2d, 0x92, 0x7e,
-  0x7f, 0x74, 0x1d, 0xc7, 0xe9, 0xb5, 0x68, 0xe9,
-  0xf7, 0x7e, 0x8d, 0x6a, 0x74, 0x7c, 0xf0, 0x6a,
-  0x31, 0x3c, 0xa3, 0xdf, 0x3a, 0x7a, 0xb5, 0x50,
-  0x1d, 0x16, 0x3c, 0x00, 0x8f, 0xcf, 0x95, 0xe0,
-  0xd5, 0xe7, 0x4e, 0x5f, 0xbc, 0xe8, 0x68, 0xf0,
-  0xee, 0x51, 0x3f, 0x2b, 0x33, 0xfe, 0xd2, 0x74,
-  0xaa, 0x74, 0x78, 0xdf, 0x71, 0x74, 0xc0, 0x52,
-  0xa6, 0x08, 0x4a, 0x8f, 0x1a, 0xb0, 0x8a, 0xcf,
-  0xee, 0x7f, 0xf2, 0xf6, 0xf1, 0x4e, 0x34, 0x33,
-  0xdb, 0x75, 0x35, 0x3a, 0x72, 0xfd, 0xa3, 0xa6,
-  0xfa, 0x9d, 0x0d, 0x1b, 0x11, 0x1c, 0x9e, 0x10,
-  0x63, 0x79, 0xd3, 0xb7, 0x8e, 0x93, 0xa1, 0x51,
-  0x6f, 0x8a, 0x9e, 0x21, 0xb1, 0x1c, 0xd6, 0xb9,
-  0xd3, 0x82, 0x10, 0x95, 0x3f, 0xf6, 0x26, 0xcb,
-  0x46, 0xfc, 0xb7, 0x52, 0x53, 0x8b, 0xc9, 0xef,
-  0x0b, 0x7e, 0xc7, 0x48, 0x4e, 0x9f, 0x33, 0xd7,
-  0x07, 0x1d, 0x14, 0x1e, 0xde, 0xec, 0x97, 0x50,
-  0xf9, 0xfc, 0x9e, 0xaf, 0xf1, 0xb7, 0x1d, 0x36,
-  0x5c, 0xe8, 0xa4, 0xf2, 0x2c, 0x67, 0x3d, 0x7f,
-  0xe3, 0xce, 0x9f, 0xfd, 0xea, 0xdb, 0x36, 0xfe,
-  0x36, 0xfe, 0x54, 0xe8, 0x13, 0xed, 0xb9, 0x0c,
-  0x9c, 0xab, 0x9b, 0x1b, 0x31, 0x63, 0x28, 0xb0,
-  0xb1, 0xb2, 0xd0, 0xf9, 0xe3, 0xbf, 0x99, 0x56,
-  0x16, 0x17, 0x7d, 0xdf, 0x09, 0x09, 0xf0, 0xa7,
-  0x72, 0x1a, 0x2b, 0x79, 0xff, 0x73, 0xdd, 0x82,
-  0x9d, 0xc8, 0x68, 0x9c, 0x24, 0xec, 0x3f, 0x66,
-  0x18, 0x4f, 0x85, 0x3b, 0x90, 0xd1, 0x68, 0xcf,
-  0x63, 0x5e, 0xd2, 0x74, 0x9d, 0x87, 0xa9, 0x63,
-  0x09, 0xe4, 0xee, 0x43, 0x45, 0xb5, 0x3f, 0x59,
-  0x58, 0xbe, 0xd8, 0xe9, 0x9d, 0x82, 0x7b, 0x17,
-  0x2b, 0x9f, 0xce, 0xc1, 0x4e, 0xe4, 0x34, 0x5c,
-  0xb3, 0xf9, 0xd8, 0x29, 0xdc, 0x86, 0x8b, 0xb6,
-  0x15, 0x9c, 0xad, 0x41, 0x43, 0xe3, 0xff, 0xda,
-  0x1b, 0x7a, 0x65, 0x87, 0xfa, 0x76, 0x13, 0x77,
-  0x19, 0x2d, 0x9e, 0xfe, 0xff, 0x52, 0xcb, 0x9d,
-  0xcf, 0xe7, 0x60, 0xa7, 0x72, 0x1a, 0x2a, 0x79,
-  0xe4, 0xee, 0x43, 0x45, 0x73, 0x3f, 0x9d, 0x82,
-  0x9d, 0xc8, 0x68, 0xb3, 0xa0, 0x4f, 0x9a, 0xc5,
-  0x73, 0xe1, 0x4e, 0xe4, 0x34, 0x48, 0x53, 0xfd,
-  0xea, 0x6b, 0x7f, 0xab, 0x2a, 0x74, 0xcf, 0x76,
-  0x1f, 0x50, 0x0c, 0x27, 0x9b, 0xa5, 0x95, 0x87,
-  0x4f, 0xec, 0xb5, 0x6b, 0x83, 0x41, 0xd2, 0x76,
-  0x26, 0x23, 0xd0, 0x8b, 0xa9, 0x6d, 0xc9, 0xe7,
-  0xff, 0x39, 0x9c, 0xf7, 0x60, 0xa7, 0x72, 0x1a,
-  0x27, 0xc8, 0x45, 0x49, 0x7b, 0xb8, 0xec, 0xac,
-  0x8f, 0x3e, 0x14, 0xee, 0x43, 0x45, 0x65, 0x3f,
-  0xee, 0x7b, 0xb0, 0x53, 0xb9, 0x0d, 0x13, 0x74,
-  0xde, 0x76, 0x1f, 0xb3, 0x0c, 0x27, 0xc2, 0x9d,
-  0xc8, 0x68, 0x95, 0xa7, 0xfb, 0x4d, 0xbd, 0xa3,
-  0x54, 0xca, 0x9d, 0x3e, 0x73, 0x39, 0xee, 0xc3,
-  0xed, 0xe3, 0x09, 0xf0, 0xa7, 0x72, 0x1a, 0x25,
-  0xc9, 0xfe, 0xf7, 0x3e, 0xff, 0x56, 0x54, 0xe9,
-  0xe6, 0xde, 0xfa, 0x9d, 0x3e, 0x73, 0x39, 0xee,
-  0xc4, 0x45, 0xd8, 0xc3, 0x8e, 0x27, 0xfe, 0x77,
-  0x3d, 0xd8, 0x29, 0xdc, 0x86, 0x88, 0xee, 0x7f,
-  0xaf, 0x6c, 0x7b, 0xbb, 0xf5, 0x3a, 0x7e, 0x6e,
-  0x7d, 0x53, 0x3e, 0x74, 0xfd, 0xba, 0x7f, 0x2d,
-  0xd7, 0x3a, 0x7c, 0x29, 0xdc, 0x86, 0x8a, 0x86,
-  0x7d, 0x96, 0xbe, 0x50, 0x74, 0xff, 0xff, 0x6b,
-  0xdb, 0xbf, 0x51, 0x6e, 0xf5, 0xd6, 0xde, 0xbd,
-  0x73, 0x63, 0xa4, 0xed, 0xd1, 0x32, 0x46, 0xe1,
-  0x7e, 0x18, 0xdc, 0xc3, 0x70, 0x9e, 0x7c, 0x29,
-  0xdc, 0x86, 0x8a, 0xa2, 0x7f, 0xdc, 0xf7, 0x60,
-  0xa7, 0x72, 0x1a, 0x26, 0xb9, 0x3b, 0x0f, 0xd9,
-  0x86, 0x13, 0xf9, 0xd8, 0x29, 0xdc, 0x86, 0x8a,
-  0xb2, 0x7f, 0xe7, 0x73, 0xdd, 0x82, 0x9d, 0xc8,
-  0x68, 0x91, 0x27, 0xc2, 0x9d, 0xc8, 0x68, 0xb4,
-  0xa7, 0xfd, 0xcf, 0x76, 0x0a, 0x77, 0x21, 0xa2,
-  0x7d, 0x93, 0xb0, 0xfd, 0x98, 0x61, 0x3f, 0xf9,
-  0xcc, 0xe7, 0xbb, 0x05, 0x3b, 0x90, 0xd1, 0x42,
-  0x4f, 0xad, 0xea, 0x14, 0x4e, 0x9f, 0x0a, 0x77,
-  0x21, 0xa2, 0x8f, 0x9f, 0xff, 0xb3, 0x6b, 0x2e,
-  0xf7, 0x5f, 0xfc, 0x0a, 0xd5, 0x40, 0x54, 0xf9,
-  0xcc, 0xe7, 0xb9, 0x51, 0x69, 0x84, 0xfb, 0x86,
-  0x10, 0xab, 0xc5, 0x94, 0x43, 0x21, 0xe9, 0x78,
-  0x99, 0xa6, 0x35, 0xc4, 0x86, 0x95, 0x24, 0xed,
-  0x1d, 0xda, 0x18, 0x40, 0x27, 0xbc, 0x60, 0xd3,
-  0xf9, 0xd8, 0x29, 0xdc, 0x86, 0x88, 0x8a, 0x7e,
-  0xc1, 0x4e, 0xe4, 0x34, 0x45, 0x73, 0xfd, 0xbb,
-  0x76, 0x0a, 0x77, 0x21, 0xa2, 0xb8, 0x87, 0x1f,
-  0xd7, 0x1a, 0xcf, 0x65, 0xba, 0xe7, 0x4f, 0xec,
-  0xf0, 0x80, 0x1a, 0xd4, 0xe9, 0x6e, 0x9f, 0x3d,
-  0x3a, 0x90, 0x4f, 0xfd, 0xde, 0x7f, 0xbf, 0x7d,
-  0x6c, 0x38, 0x74, 0xfb, 0x3d, 0xb0, 0xe1, 0xd3,
-  0xaf, 0x5f, 0x58, 0xfa, 0xae, 0x89, 0x3e, 0x14,
-  0xee, 0x43, 0x45, 0x3d, 0x0d, 0xc4, 0x7d, 0xac,
-  0x25, 0xf0, 0xd2, 0x7f, 0xf7, 0x3d, 0xdb, 0x7f,
-  0x83, 0x5a, 0xa8, 0x0e, 0x87, 0x22, 0x07, 0x63,
-  0x79, 0xce, 0xdb, 0x0e, 0x9f, 0x2b, 0xc1, 0xab,
-  0xce, 0x9e, 0x4e, 0xe4, 0x34, 0x56, 0x70, 0xd1,
-  0xe9, 0x89, 0x44, 0xfd, 0x43, 0x17, 0xef, 0xa9,
-  0xd3, 0x96, 0x8f, 0x1d, 0x3e, 0xb8, 0x37, 0xfd,
-  0xe7, 0x4e, 0xd7, 0xaa, 0x74, 0xfb, 0x1a, 0xa3,
-  0x50, 0x1d, 0x27, 0x62, 0x37, 0x04, 0x8a, 0xc5,
-  0xdc, 0x39, 0xf2, 0xad, 0xe3, 0x93, 0xff, 0x3b,
-  0x9e, 0xec, 0x14, 0xee, 0x43, 0x44, 0x8b, 0x3f,
-  0x9d, 0x82, 0x9d, 0xc8, 0x68, 0xb2, 0x67, 0xf3,
-  0xb0, 0x53, 0xb9, 0x0d, 0x16, 0xc4, 0xec, 0xae,
-  0x1d, 0x3e, 0x14, 0xee, 0x43, 0x45, 0xb7, 0x27,
-  0x3c, 0xf2, 0xb0, 0x6a, 0x7f, 0xcd, 0xc6, 0xe6,
-  0xeb, 0x5e, 0xd9, 0xf5, 0x01, 0xd3, 0xf2, 0xfd,
-  0xfb, 0x6a, 0xc3, 0xa7, 0xc2, 0x9d, 0xc8, 0x68,
-  0xbc, 0x27, 0xaf, 0xb9, 0x96, 0x3a, 0x7f, 0xe5,
-  0xde, 0xca, 0x5f, 0x7c, 0xfd, 0xea, 0x74, 0xfb,
-  0x3e, 0x06, 0xf5, 0x3a, 0x7c, 0xbb, 0xf5, 0xea,
-  0x9d, 0x3a, 0xea, 0x03, 0xa4, 0xed, 0xd7, 0x93,
-  0x84, 0xa1, 0x37, 0x0b, 0xe9, 0x30, 0xb1, 0x20,
-  0x11, 0xfe, 0x53, 0x72, 0x99, 0xde, 0xca, 0x4e,
-  0x9f, 0x0a, 0x77, 0x21, 0xa2, 0xf4, 0x9f, 0xf7,
-  0xfa, 0xef, 0x5d, 0x37, 0xf5, 0x07, 0x4f, 0xb1,
-  0x96, 0xed, 0x8e, 0x93, 0xb6, 0x45, 0xa6, 0x0e,
-  0x6f, 0x30, 0x6f, 0x41, 0x85, 0x64, 0x52, 0xd1,
-  0x0b, 0x5c, 0x8f, 0xc1, 0x09, 0x3d, 0x1a, 0x58,
-  0xae, 0x31, 0x30, 0x07, 0x7f, 0x84, 0x2e, 0xb1,
-  0xd5, 0x86, 0x33, 0x69, 0xec, 0xb7, 0x5c, 0xe9,
-  0xfd, 0x9e, 0x10, 0x03, 0x5a, 0x9d, 0x2d, 0xd3,
-  0xe7, 0xa7, 0x52, 0x09, 0xf0, 0xa7, 0x72, 0x1a,
-  0x22, 0x39, 0xff, 0xeb, 0x6b, 0x5a, 0xe3, 0x3f,
-  0x8d, 0xb4, 0x2b, 0x75, 0x3a, 0x7f, 0xcf, 0x5a,
-  0x07, 0x2f, 0x7f, 0x5c, 0xe9, 0xff, 0xfe, 0x5b,
-  0x77, 0xae, 0xb6, 0xfe, 0x5e, 0xde, 0xb6, 0x78,
-  0x27, 0x4d, 0x43, 0x0a, 0x98, 0x21, 0x2a, 0x7f,
-  0xe7, 0xb9, 0x2d, 0xe6, 0xac, 0xb4, 0x38, 0x06,
-  0xb4, 0x22, 0xf3, 0xfb, 0x37, 0x7f, 0xcb, 0x75,
-  0xce, 0x9f, 0xff, 0x91, 0xc3, 0xdf, 0xf5, 0xdc,
-  0x2b, 0x7f, 0xf0, 0x0e, 0x86, 0xe2, 0xa7, 0x1c,
-  0x2d, 0x43, 0x0a, 0x56, 0x84, 0xfb, 0xa1, 0x25,
-  0x75, 0xd6, 0xc6, 0xb3, 0xe1, 0x4e, 0xe4, 0x34,
-  0x45, 0xd3, 0xeb, 0x83, 0x7f, 0xde, 0x5b, 0x3d,
-  0x92, 0x76, 0x1f, 0x47, 0x18, 0x43, 0x93, 0x09,
-  0x7c, 0x38, 0xe7, 0xfe, 0x67, 0x3d, 0xd8, 0x29,
-  0xdc, 0x86, 0x89, 0x9a, 0x75, 0x2b, 0x53, 0xa7,
-  0x27, 0x98, 0x74, 0xed, 0xd5, 0xb9, 0xba, 0x8e,
-  0x9f, 0x27, 0x5b, 0xcd, 0x1d, 0x3f, 0xf3, 0x7f,
-  0xaf, 0xe4, 0xf6, 0xd7, 0xc4, 0x3a, 0x7f, 0xff,
-  0xb5, 0xef, 0xa7, 0xf3, 0x6b, 0x6b, 0xa2, 0xca,
-  0xf1, 0x5a, 0x0e, 0x8c, 0x45, 0x8d, 0x91, 0xe7,
-  0xff, 0xdb, 0x7b, 0xf4, 0x65, 0x7d, 0xd6, 0x70,
-  0x42, 0x12, 0xa7, 0x93, 0xb9, 0x0d, 0x16, 0x7c,
-  0xff, 0xbd, 0x65, 0x7f, 0xae, 0xb7, 0xa9, 0xd3,
-  0xff, 0xde, 0x1b, 0x76, 0x8c, 0x6d, 0xfc, 0xae,
-  0x7c, 0xe9, 0xc1, 0x08, 0x4a, 0x9f, 0xf7, 0x3e,
-  0xbf, 0xc4, 0xdb, 0x04, 0xa7, 0x17, 0x93, 0xfc,
-  0xb6, 0xf6, 0xdf, 0xee, 0x68, 0xe9, 0xfe, 0xf7,
-  0xf6, 0xdf, 0xb6, 0xb7, 0xa9, 0xd0, 0x89, 0xf8,
-  0x8a, 0xc3, 0x0a, 0xec, 0x7c, 0x06, 0xdb, 0xa5,
-  0xb6, 0x39, 0x9f, 0xff, 0xff, 0xb3, 0x01, 0x5c,
-  0xcf, 0xe9, 0xde, 0x3f, 0x5c, 0xb3, 0xab, 0xfc,
-  0xa1, 0x98, 0xc3, 0xa7, 0x55, 0x68, 0x3a, 0x76,
-  0xe6, 0x58, 0xe8, 0x7a, 0x31, 0x2b, 0x08, 0xab,
-  0x8e, 0x4f, 0x52, 0x0d, 0x50, 0xe9, 0xf5, 0xbe,
-  0xb8, 0x26, 0x4f, 0xfb, 0xc2, 0xfc, 0x1a, 0x35,
-  0xed, 0x8d, 0x10, 0x6b, 0x8d, 0x2c, 0xfb, 0x93,
-  0xcc, 0x53, 0xa7, 0xe7, 0xdb, 0xfd, 0x4d, 0xce,
-  0x96, 0x21, 0xe9, 0xfc, 0x96, 0x7f, 0xff, 0xdc,
-  0x1b, 0xe5, 0xae, 0xb9, 0xfa, 0x6f, 0x83, 0xea,
-  0x39, 0x87, 0x43, 0xd3, 0x40, 0xc8, 0x57, 0xfc,
-  0x9a, 0x7e, 0x1c, 0xda, 0xb6, 0x53, 0xa7, 0xff,
-  0xf6, 0xbf, 0xed, 0x3a, 0x37, 0xff, 0xaf, 0x5f,
-  0x53, 0x6f, 0x04, 0xe9, 0xff, 0xfe, 0xad, 0x54,
-  0x6e, 0xae, 0x66, 0x5e, 0xbb, 0xeb, 0xcf, 0xc3,
-  0xa7, 0xad, 0x9e, 0x6c, 0x74, 0x79, 0x11, 0x36,
-  0x66, 0x99, 0x9b, 0xa1, 0xa2, 0xfc, 0x9f, 0xf9,
-  0xf7, 0xd5, 0xef, 0x65, 0xee, 0xac, 0x3a, 0x7f,
-  0xef, 0x67, 0xf3, 0x2b, 0xa1, 0xf5, 0x61, 0xd1,
-  0x4a, 0x22, 0xea, 0x8d, 0x3d, 0xff, 0xaa, 0x1d,
-  0x0a, 0x98, 0xd6, 0xc4, 0x79, 0x0b, 0x3e, 0x24,
-  0x9f, 0xff, 0xf9, 0xbd, 0x6d, 0xe6, 0x39, 0xa7,
-  0xf0, 0xef, 0xb7, 0xa9, 0xaa, 0x7a, 0x83, 0xa7,
-  0xfd, 0xcf, 0x67, 0x3e, 0xf5, 0x5d, 0x27, 0x4f,
-  0x65, 0x7d, 0xf3, 0xa3, 0xe7, 0xc1, 0xa9, 0xfc,
-  0xf6, 0xfd, 0x7a, 0xa7, 0x4f, 0xfa, 0xf5, 0x07,
-  0xa9, 0xa5, 0xf9, 0x73, 0xa1, 0x4f, 0x97, 0x09,
-  0x26, 0x6b, 0x53, 0xa4, 0xc3, 0xa2, 0x93, 0x50,
-  0xdd, 0x8c, 0x4f, 0xff, 0xfa, 0xde, 0xa6, 0xf9,
-  0x4d, 0xc4, 0x56, 0xe0, 0xdf, 0xf7, 0xdb, 0x0e,
-  0x9c, 0x10, 0x84, 0xa9, 0xed, 0xb6, 0xef, 0x94,
-  0xe2, 0xf2, 0x7f, 0xdd, 0x64, 0xf7, 0x68, 0xaf,
-  0x58, 0xe8, 0x54, 0xc8, 0x90, 0x9f, 0xd0, 0x8b,
-  0xb1, 0x94, 0xff, 0xd9, 0xfa, 0x6f, 0x83, 0xea,
-  0x39, 0x87, 0x4f, 0xb2, 0xef, 0x65, 0x8e, 0x85,
-  0x3e, 0xba, 0xa2, 0x4c, 0x0b, 0x1d, 0x3f, 0x50,
-  0xd3, 0xdb, 0x83, 0x41, 0xd3, 0xfb, 0x4d, 0xb2,
-  0xf6, 0xf5, 0xce, 0x9b, 0xc2, 0x74, 0x6e, 0xa3,
-  0xfe, 0xf1, 0xa5, 0x8d, 0x67, 0xfe, 0xd9, 0x76,
-  0x15, 0xbf, 0x93, 0xdb, 0x1d, 0x3f, 0x5b, 0x5a,
-  0x1a, 0xb7, 0x8e, 0x8d, 0x8f, 0xda, 0xc8, 0xb2,
-  0x73, 0x74, 0x66, 0xee, 0xee, 0xb0, 0xe2, 0x8d,
-  0xd0, 0x57, 0xb4, 0x36, 0x32, 0x50, 0x9d, 0x31,
-  0x94, 0xf8, 0xd5, 0xa8, 0xe2, 0x04, 0xd5, 0x85,
-  0x96, 0x94, 0x1b, 0xc8, 0x20, 0x86, 0xd7, 0xe1,
-  0x11, 0x58, 0xda, 0xaf, 0x0a, 0xc0, 0x90, 0xee,
-  0x42, 0x53, 0x7c, 0x2a, 0xe1, 0xcc, 0xf9, 0x0b,
-  0x53, 0x8a, 0x67, 0xff, 0x39, 0x9c, 0xf7, 0x60,
-  0xa7, 0x72, 0x1a, 0x26, 0xc9, 0xfc, 0xec, 0x14,
-  0xee, 0x43, 0x45, 0x5b, 0x3f, 0x9e, 0xfd, 0x6f,
-  0xf5, 0x79, 0xd3, 0xd9, 0x6e, 0xb9, 0xd2, 0xdd,
-  0x30, 0xf5, 0x3e, 0x69, 0x3e, 0x14, 0xee, 0x43,
-  0x45, 0x69, 0x3f, 0xfc, 0x8a, 0x38, 0x0e, 0x67,
-  0x3d, 0x7c, 0x87, 0x4f, 0xff, 0x3e, 0xb9, 0xf5,
-  0x67, 0x65, 0xee, 0xac, 0x3a, 0x6b, 0xdd, 0x51,
-  0x2f, 0xc9, 0x53, 0xf9, 0x5b, 0x6f, 0xbf, 0xd4,
-  0x07, 0x4f, 0xd4, 0x65, 0xbd, 0x8c, 0x3a, 0x7f,
-  0xb1, 0xbf, 0xea, 0x1a, 0x5f, 0x53, 0xa7, 0xf3,
-  0xf2, 0xfd, 0xf0, 0x6a, 0x74, 0x9c, 0xdc, 0x4f,
-  0xcb, 0x0b, 0x3d, 0x0c, 0x7b, 0x16, 0xf1, 0xb7,
-  0xcb, 0x6e, 0x79, 0x3f, 0x9d, 0x82, 0x9d, 0xc8,
-  0x68, 0xb0, 0x27, 0xc2, 0x9d, 0xc8, 0x68, 0x9d,
-  0x67, 0xff, 0xf5, 0x96, 0x8d, 0xb1, 0x8e, 0xad,
-  0x72, 0xde, 0xae, 0xb4, 0x1d, 0x3e, 0x73, 0x39,
-  0xee, 0xc4, 0x4a, 0xb4, 0x61, 0x3e, 0x14, 0xee,
-  0x43, 0x45, 0xb3, 0x3f, 0xe0, 0x2d, 0x5d, 0x6f,
-  0x27, 0x09, 0xd2, 0x76, 0x1f, 0x67, 0x18, 0x4f,
-  0x27, 0x72, 0x1a, 0x2e, 0x69, 0x30, 0xe9, 0x9d,
-  0x82, 0x6e, 0xc2, 0x57, 0x3f, 0x9d, 0x82, 0x9d,
-  0xc8, 0x68, 0xbb, 0xe7, 0x9d, 0xa7, 0x60, 0x1d,
-  0x0a, 0xda, 0xcb, 0x65, 0x3e, 0xe5, 0x0c, 0x29,
-  0x52, 0xf4, 0xa8, 0x11, 0x72, 0x64, 0x34, 0x01,
-  0x0a, 0xca, 0xb0, 0xdc, 0xaf, 0x79, 0xdc, 0xff,
-  0xbf, 0xce, 0x5a, 0xd5, 0x9c, 0xf3, 0xa7, 0xf7,
-  0xe8, 0xc6, 0xfb, 0xae, 0x93, 0xa7, 0xc2, 0x9d,
-  0xc8, 0x68, 0x95, 0xe7, 0xfd, 0xfe, 0x0e, 0xd6,
-  0x5a, 0x30, 0x27, 0x4f, 0x6b, 0xc2, 0xf3, 0xa7,
-  0xff, 0xf7, 0xaf, 0xcc, 0xef, 0x82, 0xc1, 0xef,
-  0xd0, 0x9e, 0xa0, 0xe8, 0xd9, 0x10, 0x7c, 0x43,
-  0x1b, 0x23, 0x96, 0xd0, 0xc2, 0x9d, 0xcf, 0x72,
-  0xa6, 0xed, 0x87, 0x15, 0x8c, 0x56, 0x75, 0xd7,
-  0x62, 0xa7, 0xff, 0x5b, 0xbd, 0x75, 0x7f, 0x86,
-  0x8d, 0x40, 0x54, 0xfe, 0xe4, 0x76, 0xc2, 0xdd,
-  0xb9, 0x4f, 0x9e, 0xa3, 0x92, 0x72, 0x2a, 0xae,
-  0x64, 0x76, 0x6d, 0xa1, 0x5b, 0x3f, 0xf9, 0xcc,
-  0xe7, 0xbb, 0x05, 0x3b, 0x90, 0xd1, 0x30, 0xcf,
-  0xff, 0xd8, 0xed, 0xe3, 0xc0, 0x76, 0x9b, 0xbc,
-  0x2b, 0x57, 0x9d, 0x3f, 0xf6, 0xe9, 0x94, 0xbf,
-  0x5e, 0xbf, 0xd5, 0xe7, 0x4f, 0xe5, 0xea, 0x2f,
-  0xa7, 0x84, 0xe9, 0xf7, 0x0b, 0xf9, 0x87, 0x47,
-  0xcf, 0x63, 0x53, 0x39, 0xf9, 0x8b, 0x9f, 0xbe,
-  0xe1, 0xd3, 0xe5, 0xcf, 0xdf, 0x70, 0xe9, 0xfa,
-  0xde, 0xbd, 0x7a, 0x9d, 0x07, 0xb0, 0xc2, 0xf9,
-  0xff, 0xff, 0x7f, 0x02, 0xdf, 0x7c, 0xb6, 0x8f,
-  0xe5, 0x1e, 0xcf, 0xd2, 0xfa, 0x9d, 0x3f, 0x36,
-  0xdf, 0x7f, 0xa8, 0x0e, 0x9f, 0xfc, 0xb7, 0x02,
-  0xbf, 0x29, 0xbd, 0x1a, 0x84, 0xe8, 0x53, 0xfd,
-  0xf1, 0x8c, 0xfd, 0x5f, 0x69, 0x67, 0x5c, 0xe9,
-  0xff, 0xff, 0x0e, 0x36, 0x5f, 0xdf, 0x46, 0xff,
-  0xad, 0xbb, 0xd7, 0x5b, 0xd4, 0xe9, 0x65, 0x28,
-  0x9f, 0x12, 0xf9, 0xef, 0xa8, 0x37, 0x9d, 0x3d,
-  0xdb, 0xf6, 0xc3, 0xa4, 0xe6, 0xe2, 0xb8, 0x3d,
-  0xa1, 0x44, 0x8f, 0x6d, 0x24, 0x5a, 0x1e, 0x1f,
-  0x86, 0x05, 0xca, 0x35, 0x23, 0x9f, 0x0a, 0x77,
-  0x21, 0xa2, 0xae, 0x9f, 0xe7, 0xbb, 0x05, 0x3b,
-  0x90, 0xd1, 0x1e, 0x49, 0xd8, 0x7e, 0x3c, 0x61,
-  0x3f, 0x9d, 0x82, 0x9d, 0xc8, 0x68, 0xb0, 0x67,
-  0xf3, 0xb0, 0x53, 0xb9, 0x0d, 0x16, 0x54, 0xfe,
-  0x76, 0x0a, 0x77, 0x21, 0xa2, 0xd3, 0x9e, 0x4e,
-  0xe4, 0x34, 0x5b, 0x93, 0xff, 0x2e, 0x0e, 0x7f,
-  0x45, 0xb2, 0x90, 0x9d, 0x02, 0x7d, 0xf5, 0x2b,
-  0x9f, 0xe5, 0xfe, 0xac, 0x5a, 0xdf, 0xc7, 0x4f,
-  0xfb, 0x9e, 0xec, 0x14, 0xee, 0x43, 0x45, 0x0f,
-  0x3f, 0x57, 0xa9, 0xad, 0xfc, 0x74, 0xfd, 0xf6,
-  0xe6, 0x0a, 0xd4, 0xe9, 0xff, 0xfb, 0x36, 0xb2,
-  0xef, 0x75, 0xff, 0xc0, 0xad, 0x54, 0x05, 0x49,
-  0xd8, 0x9a, 0xd7, 0x88, 0x58, 0x73, 0x74, 0x6d,
-  0x4b, 0xb7, 0x0b, 0xe7, 0xf3, 0xb0, 0x53, 0xb9,
-  0x0d, 0x17, 0x9c, 0x2b, 0x22, 0xc9, 0xe8, 0x9b,
-  0x29, 0x64, 0xbe, 0x1a, 0x61, 0xfe, 0x24, 0xcc,
-  0x3b, 0xb1, 0xdf, 0xe5, 0x02, 0x36, 0x61, 0x9f,
-  0xce, 0xc1, 0x4e, 0xe4, 0x34, 0x52, 0xd3, 0xf9,
-  0xd8, 0x29, 0xdc, 0x86, 0x8b, 0x0a, 0x7f, 0x3b,
-  0x05, 0x3b, 0x90, 0xd1, 0x65, 0xcf, 0x3b, 0x4e,
-  0xeb, 0xe6, 0xea, 0x74, 0xe7, 0x6f, 0x61, 0xd3,
-  0xc8, 0xe5, 0xaa, 0x1e, 0x96, 0xa6, 0x93, 0xff,
-  0x9c, 0xce, 0x7b, 0xb0, 0x53, 0xb9, 0x0d, 0x14,
-  0x64, 0xfe, 0x72, 0xb6, 0x51, 0x50, 0x1d, 0x0f,
-  0x4e, 0xfc, 0x4e, 0xd8, 0x77, 0xd0, 0x8d, 0xa9,
-  0xc5, 0xd4, 0xa7, 0xfe, 0x77, 0x3d, 0xd8, 0x29,
-  0xdc, 0x86, 0x88, 0xe6, 0x7f, 0xf3, 0x99, 0xcf,
-  0x76, 0x0a, 0x77, 0x21, 0xa2, 0x72, 0x9f, 0xce,
-  0xc1, 0x4e, 0xe4, 0x34, 0x59, 0x93, 0xff, 0x39,
-  0x40, 0x2b, 0x7b, 0x75, 0x2f, 0x3a, 0x7f, 0x3b,
-  0x05, 0x3b, 0x90, 0xd1, 0x6e, 0xcf, 0xfe, 0x73,
-  0x39, 0xee, 0xc1, 0x4e, 0xe4, 0x34, 0x52, 0x13,
-  0xff, 0x3b, 0x9e, 0xec, 0x14, 0xee, 0x43, 0x44,
-  0xa5, 0x14, 0x27, 0xea, 0xd2, 0x63, 0x14, 0x80,
-  0x77, 0xf4, 0x3b, 0x9d, 0xb7, 0xa9, 0x4f, 0xfb,
-  0x9e, 0xec, 0x14, 0xee, 0x43, 0x44, 0xed, 0x3f,
-  0xfe, 0xf6, 0xda, 0xb1, 0x5b, 0xfb, 0x6f, 0xaf,
-  0xf1, 0x0e, 0x93, 0x98, 0x89, 0xfe, 0x46, 0x9f,
-  0xfb, 0x99, 0x6c, 0x4e, 0xb2, 0xef, 0x79, 0xd3,
-  0xff, 0x7f, 0x2d, 0xd4, 0x65, 0x7f, 0xd4, 0x9d,
-  0x36, 0xe3, 0xb6, 0x44, 0x3d, 0x50, 0xe1, 0x88,
-  0xe2, 0xdc, 0x85, 0x7c, 0xf8, 0x53, 0xb9, 0x0d,
-  0x11, 0x64, 0xff, 0xb9, 0xee, 0xc1, 0x4e, 0xe4,
-  0x34, 0x4b, 0xb3, 0xff, 0xf6, 0x6d, 0x65, 0xde,
-  0xeb, 0xff, 0x81, 0x5a, 0xa8, 0x0a, 0x93, 0xb1,
-  0x1a, 0x6c, 0x30, 0xdc, 0x46, 0x9f, 0xfc, 0xe6,
-  0x73, 0xdd, 0x82, 0x9d, 0xc8, 0x68, 0x98, 0xa7,
-  0xec, 0x14, 0xee, 0x43, 0x45, 0x53, 0x3f, 0xff,
-  0xf8, 0x7a, 0xd4, 0xbf, 0x2e, 0xeb, 0x75, 0x47,
-  0xc1, 0xbd, 0xbc, 0x2f, 0x3a, 0x1c, 0x8a, 0xce,
-  0x35, 0x9f, 0xfc, 0xe6, 0x73, 0xdd, 0x82, 0x9d,
-  0xc8, 0x68, 0x9d, 0x27, 0xf7, 0xb8, 0x55, 0xfc,
-  0xd8, 0xe9, 0xf3, 0x4a, 0xd2, 0xd4, 0xe9, 0xf8,
-  0x39, 0xe6, 0xd9, 0xf3, 0xa7, 0xbd, 0x65, 0x77,
-  0x8f, 0x5a, 0xa5, 0x13, 0xff, 0x6b, 0x5b, 0xad,
-  0x2e, 0xd5, 0xaf, 0x30, 0xe8, 0x62, 0x20, 0xac,
-  0x73, 0x3f, 0xee, 0x7b, 0xb0, 0x53, 0xb9, 0x0d,
-  0x13, 0xbc, 0xfa, 0xfa, 0xf3, 0x3c, 0x54, 0x9d,
-  0xb2, 0x73, 0x79, 0x18, 0x53, 0x08, 0xf9, 0x1a,
-  0x7f, 0xf3, 0x99, 0xcf, 0x76, 0x0a, 0x77, 0x21,
-  0xa2, 0x85, 0x9f, 0xfc, 0xe6, 0x73, 0xdd, 0x82,
-  0x9d, 0xc8, 0x68, 0xa4, 0xa7, 0xff, 0xf6, 0x55,
-  0xdb, 0xf1, 0xab, 0x73, 0x2f, 0x65, 0xbe, 0xac,
-  0x3a, 0x28, 0x5c, 0x96, 0x79, 0xc2, 0x43, 0xf8,
-  0x48, 0x99, 0x1f, 0x68, 0x12, 0x75, 0x52, 0xdc,
-  0x52, 0x9f, 0xce, 0xc1, 0x4e, 0xe4, 0x34, 0x44,
-  0x93, 0xff, 0x9c, 0xce, 0x7b, 0xb0, 0x53, 0xb9,
-  0x0d, 0x12, 0xf4, 0xf8, 0x53, 0xb9, 0x0d, 0x14,
-  0xbc, 0xff, 0xec, 0x7a, 0x82, 0xa2, 0xb4, 0xbf,
-  0xcc, 0x3a, 0x7c, 0xdf, 0xe6, 0x2d, 0x4e, 0x9f,
-  0x73, 0x6c, 0x1a, 0x9d, 0x25, 0xd8, 0xf4, 0x58,
-  0x55, 0x27, 0x62, 0x3c, 0x9a, 0x30, 0xbc, 0x26,
-  0xa7, 0xf3, 0xb0, 0x53, 0xb9, 0x0d, 0x14, 0xe4,
-  0xff, 0xbc, 0x3d, 0x5b, 0x66, 0x7d, 0x0e, 0x9f,
-  0xf6, 0x59, 0x47, 0x1c, 0x10, 0x84, 0xa9, 0xbc,
-  0x13, 0xa6, 0xa1, 0xdb, 0x22, 0x37, 0x70, 0xed,
-  0xbc, 0xf2, 0x7c, 0x29, 0xdc, 0x86, 0x8a, 0xf2,
-  0x7f, 0xfe, 0xcd, 0xac, 0xbb, 0xdd, 0x7f, 0xf0,
-  0x2b, 0x55, 0x01, 0x52, 0x76, 0x22, 0x37, 0x70,
-  0xc2, 0x7f, 0xe7, 0x73, 0xdd, 0x82, 0x9d, 0xc8,
-  0x68, 0x91, 0xe7, 0x78, 0x0a, 0x74, 0xe4, 0xc6,
-  0x14, 0xe2, 0xee, 0x7c, 0x29, 0xdc, 0x86, 0x89,
-  0x22, 0x79, 0xdc, 0xf7, 0x29, 0xec, 0xe1, 0x4c,
-  0xff, 0xce, 0xe7, 0xbb, 0x05, 0x3b, 0x90, 0xd1,
-  0x25, 0x4f, 0x85, 0x3b, 0x90, 0xd1, 0x78, 0xcf,
-  0xda, 0xfe, 0x9e, 0xa6, 0xa7, 0x4f, 0xab, 0x5b,
-  0xe2, 0x1d, 0x3f, 0xcf, 0x76, 0x0a, 0x77, 0x21,
-  0xa2, 0x4d, 0x93, 0xb1, 0x18, 0xf4, 0x98, 0x09,
-  0x87, 0x13, 0x42, 0xae, 0xe4, 0xd0, 0x76, 0xf8,
-  0xd1, 0x36, 0x3b, 0xf4, 0x32, 0x1a, 0x86, 0x8b,
-  0x0a, 0xed, 0x0c, 0x0b, 0x9b, 0xeb, 0x18, 0x9c,
-  0x2c, 0x6e, 0xd9, 0x14, 0x47, 0x5c, 0xf8, 0xf2,
-  0x76, 0x94, 0x35, 0x96, 0xeb, 0x5b, 0x4c, 0xa5,
-  0x84, 0xaf, 0xf7, 0xa9, 0x9e, 0x7b, 0xf4, 0xe7,
-  0xa6, 0xee, 0x3b, 0x06, 0xa9, 0xd8, 0x63, 0x48,
-  0xf5, 0x66, 0x23, 0x3e, 0xed, 0x3b, 0x51, 0xd4,
-  0xf7, 0x20, 0x4b, 0x0e, 0x6e, 0xe1, 0x63, 0xf9,
-  0xec, 0x6a, 0xd2, 0x57, 0x6f, 0x5d, 0x0f, 0xeb,
-  0x4c, 0x16, 0x6d, 0x29, 0x88, 0x32, 0x94, 0x37,
-  0x23, 0xeb, 0xdf, 0x3b, 0x28, 0xdf, 0x3c, 0x97,
-  0x00,
+  0xb3, 0x6f, 0x02, 0xa7, 0xd3, 0xfa, 0x5c, 0x27,
+  0xc9, 0xf2, 0xf9, 0xfb, 0xf4, 0xd5, 0xac, 0xb9,
+  0xd3, 0xff, 0xdf, 0xbb, 0x58, 0x39, 0xcc, 0x5b,
+  0x7b, 0x63, 0xa7, 0xd4, 0x6e, 0xfd, 0x94, 0x9d,
+  0x3e, 0xf5, 0x56, 0x86, 0x1f, 0x2f, 0xd9, 0xf2,
+  0xf0, 0x83, 0x53, 0xe5, 0xfb, 0x37, 0x3c, 0xf9,
+  0x7e, 0xcf, 0x6a, 0xfc, 0xa9, 0xf2, 0xfd, 0x8d,
+  0x8f, 0x47, 0xe4, 0x53, 0xe5, 0xca, 0xe7, 0xcf,
+  0x97, 0xec, 0x1f, 0x2f, 0xd9, 0xba, 0xe7, 0xcb,
+  0xf5, 0x85, 0xbc, 0x9f, 0xf3, 0xfa, 0xd5, 0x26,
+  0x7b, 0x37, 0x3c, 0x03, 0xe5, 0xfb, 0x07, 0xcb,
+  0xf6, 0x60, 0x29, 0xf2, 0xfd, 0x9f, 0xec, 0x07,
+  0x0e, 0x36, 0xcd, 0x8f, 0x97, 0xec, 0xfd, 0x96,
+  0xf5, 0x75, 0xa0, 0xf9, 0x7e, 0xc0, 0x11, 0x47,
+  0xf2, 0x2a, 0xa2, 0xcf, 0x0d, 0x0b, 0x73, 0xe5,
+  0xfb, 0x07, 0xcb, 0xf7, 0x0d, 0x74, 0xc1, 0x09,
+  0xf2, 0xfd, 0x87, 0xab, 0x11, 0xd8, 0xd7, 0x21,
+  0x09, 0x4c, 0x27, 0x44, 0xa5, 0x86, 0x35, 0x85,
+  0xd5, 0xd7, 0x82, 0x4d, 0x3d, 0x8f, 0x5d, 0x25,
+  0xcb, 0xf4, 0xe4, 0x47, 0xcf, 0xfb, 0x13, 0x6c,
+  0x10, 0xf5, 0x9a, 0x3a, 0x67, 0xd0, 0x54, 0x50,
+  0x89, 0x6a, 0x50, 0xbe, 0x7b, 0x02, 0xb9, 0x2b,
+  0xd3, 0x8c, 0x73, 0xff, 0xf5, 0x2f, 0x15, 0x6d,
+  0xcd, 0x2e, 0xd6, 0x56, 0x73, 0x47, 0x42, 0xae,
+  0xe1, 0xe1, 0x37, 0x8b, 0xfa, 0x73, 0x93, 0x52,
+  0xc9, 0xff, 0x69, 0x5a, 0x7e, 0xb6, 0xb6, 0xa8,
+  0x74, 0xfd, 0xfe, 0xd3, 0x6e, 0x79, 0xd3, 0x82,
+  0x10, 0x95, 0x3b, 0x7a, 0x80, 0xa7, 0x17, 0x93,
+  0xfe, 0xff, 0x3f, 0x78, 0xe3, 0x6e, 0x13, 0xa7,
+  0xfb, 0xfc, 0x0d, 0x0f, 0x50, 0x52, 0x74, 0x6c,
+  0x99, 0x8b, 0x10, 0x40, 0x95, 0xf2, 0xcb, 0x9f,
+  0xcf, 0xfb, 0xff, 0xf6, 0xad, 0xdd, 0x77, 0x16,
+  0xe7, 0x4e, 0x08, 0x42, 0x58, 0x84, 0x13, 0xe1,
+  0x4e, 0xe4, 0x2c, 0x42, 0x07, 0x1a, 0xa9, 0xc1,
+  0x08, 0x4b, 0x10, 0x7a, 0x0b, 0x10, 0x79, 0xc6,
+  0xaa, 0x65, 0x66, 0x22, 0x4d, 0x1a, 0xe7, 0xd7,
+  0x5b, 0xab, 0x0e, 0x9e, 0xff, 0x97, 0x49, 0xd3,
+  0xb7, 0xa8, 0x0e, 0x8a, 0x0f, 0x01, 0x84, 0x73,
+  0xe4, 0x5b, 0x2b, 0x0a, 0x9f, 0x7f, 0xbf, 0xfc,
+  0x2a, 0x6c, 0x42, 0xa6, 0x08, 0x4a, 0x8c, 0x3f,
+  0x5a, 0x92, 0xdc, 0x98, 0x22, 0x93, 0xfb, 0xfb,
+  0xd4, 0x16, 0xc6, 0xf2, 0x9c, 0x6e, 0xe1, 0x53,
+  0x80, 0xf3, 0x37, 0x43, 0x4e, 0x7f, 0xf5, 0x94,
+  0x15, 0xcc, 0xdb, 0xbf, 0xda, 0x4e, 0x9f, 0xd5,
+  0xde, 0xca, 0x87, 0xa9, 0x3a, 0x15, 0x5d, 0x8e,
+  0x26, 0x7a, 0x30, 0x51, 0x8e, 0xb3, 0x8d, 0x2a,
+  0x95, 0x38, 0x21, 0x09, 0x53, 0xe7, 0x83, 0xbf,
+  0xb1, 0x4e, 0x2f, 0x27, 0xff, 0xbf, 0x4e, 0x8a,
+  0x40, 0xbf, 0x4e, 0xa3, 0xfc, 0x74, 0xff, 0xf6,
+  0x2b, 0xb6, 0xfa, 0xea, 0x99, 0xa7, 0xc2, 0x74,
+  0xf3, 0x7d, 0x80, 0xd8, 0xe8, 0x79, 0xfb, 0xf2,
+  0x84, 0xff, 0xe7, 0xe0, 0x81, 0x9e, 0xae, 0xfa,
+  0xae, 0x1d, 0x3d, 0xed, 0xb1, 0x87, 0x42, 0xa7,
+  0x1c, 0xf3, 0x7e, 0x86, 0x57, 0xc8, 0x75, 0x4a,
+  0x9f, 0xb7, 0x75, 0xf7, 0xe9, 0x79, 0xd3, 0xfe,
+  0xe1, 0xdc, 0xf5, 0xb3, 0xa9, 0x01, 0xd3, 0xfe,
+  0xad, 0x54, 0x6e, 0xae, 0xdb, 0xc7, 0x4f, 0xfb,
+  0xfc, 0xd5, 0xb8, 0x47, 0xdb, 0x1d, 0x18, 0x8e,
+  0xf4, 0x33, 0xf2, 0x03, 0x0f, 0xa7, 0x9f, 0xbf,
+  0x1a, 0x3a, 0x7c, 0x3b, 0x66, 0x7c, 0xe9, 0xff,
+  0xb7, 0x7e, 0xcb, 0x2b, 0x6a, 0xd9, 0x69, 0x3a,
+  0x38, 0xfc, 0x2a, 0x4d, 0x3f, 0xfd, 0x97, 0xae,
+  0x35, 0x65, 0x6d, 0x96, 0xb2, 0x9d, 0x3f, 0xae,
+  0xdd, 0x5a, 0xfb, 0x74, 0xa3, 0x53, 0xa3, 0x64,
+  0x5a, 0x7c, 0x86, 0xea, 0x13, 0xff, 0xde, 0xae,
+  0x6d, 0x7a, 0xfb, 0x4d, 0xbb, 0xfe, 0x3a, 0x7f,
+  0xff, 0x7e, 0xf9, 0x6f, 0x2d, 0xfc, 0x05, 0x7b,
+  0x82, 0x10, 0x95, 0x3d, 0xb6, 0x66, 0x92, 0xa7,
+  0x3f, 0xfa, 0x9a, 0x21, 0x99, 0xc1, 0x08, 0x4a,
+  0x9d, 0x9f, 0x42, 0x9c, 0x5e, 0x4f, 0xfb, 0x28,
+  0xcd, 0xb9, 0xff, 0x5a, 0x0e, 0x80, 0x1f, 0x47,
+  0xca, 0x67, 0xf3, 0xff, 0x97, 0xbe, 0xb4, 0x1d,
+  0x0a, 0x9c, 0x4d, 0x0c, 0x34, 0x91, 0x8c, 0x2b,
+  0xb8, 0x8a, 0x7b, 0xd7, 0xf2, 0x9d, 0x3f, 0xb5,
+  0xc1, 0x00, 0x3d, 0xf3, 0xa7, 0xff, 0xca, 0xff,
+  0x6d, 0x6d, 0xf5, 0xc1, 0x4e, 0xe4, 0x34, 0x41,
+  0x91, 0x64, 0x4a, 0x5c, 0xce, 0x7d, 0x51, 0xf0,
+  0x77, 0x67, 0x4f, 0xed, 0xcc, 0xae, 0xe6, 0x0a,
+  0x9d, 0x0f, 0x4c, 0xe7, 0xd0, 0xb5, 0xa9, 0x1d,
+  0xca, 0xe7, 0xff, 0x97, 0xf4, 0x68, 0x6b, 0xdf,
+  0xcd, 0xb3, 0xfa, 0x4e, 0x9c, 0xa2, 0xd1, 0xd0,
+  0xab, 0xb9, 0x9b, 0x1d, 0xe4, 0x69, 0x08, 0x63,
+  0xe8, 0xf7, 0x3a, 0x38, 0x8d, 0x50, 0xf7, 0x15,
+  0xa7, 0xff, 0x91, 0x6b, 0x55, 0x66, 0x5f, 0xd5,
+  0xb7, 0x1d, 0x3f, 0xbf, 0xf5, 0x7b, 0x17, 0xc7,
+  0x4f, 0xeb, 0xf9, 0xb7, 0xae, 0xf5, 0x2a, 0x4c,
+  0x3a, 0x7e, 0xcf, 0xe9, 0x15, 0x77, 0x8f, 0x17,
+  0x79, 0xac, 0x62, 0x61, 0x7e, 0x4d, 0xab, 0xbc,
+  0xf0, 0xeb, 0x4b, 0xce, 0x9f, 0xdf, 0x7f, 0xf1,
+  0x8a, 0x87, 0x4e, 0x66, 0xd8, 0x74, 0x29, 0xf8,
+  0x61, 0x1f, 0x18, 0xce, 0xbf, 0xa8, 0x3a, 0x7f,
+  0xda, 0xde, 0xbb, 0xc4, 0x0c, 0xf5, 0x4e, 0x9f,
+  0xf9, 0x7f, 0xd6, 0x50, 0x38, 0x6b, 0x52, 0xa3,
+  0x64, 0x42, 0x31, 0x0a, 0x7d, 0x6f, 0x7a, 0x9a,
+  0x9d, 0x05, 0x4f, 0xd5, 0xde, 0xa2, 0xac, 0x2a,
+  0x0a, 0x82, 0xa0, 0xa8, 0x2a, 0x1e, 0x7b, 0xfe,
+  0x0a, 0x01, 0x6e, 0xa1, 0x5b, 0x81, 0x4d, 0xe1,
+  0x53, 0x5b, 0x0a, 0x9f, 0xbb, 0xae, 0xd2, 0xb0,
+  0xad, 0x05, 0xac, 0x9b, 0xb2, 0xa0, 0xa8, 0x2a,
+  0x1e, 0x5a, 0x78, 0x2a, 0x0a, 0x82, 0xa0, 0xa8,
+  0x2a, 0x0a, 0x82, 0xa2, 0x83, 0x79, 0xb0, 0x57,
+  0x82, 0x80, 0x15, 0x50, 0xa6, 0xc1, 0x50, 0x54,
+  0x15, 0x0f, 0x2d, 0x2a, 0x15, 0x05, 0x41, 0x50,
+  0x54, 0x15, 0x0f, 0x35, 0x00, 0x0a, 0xb8, 0x53,
+  0x78, 0x54, 0x15, 0x05, 0x41, 0x50, 0x54, 0x50,
+  0x6a, 0x34, 0x85, 0x08, 0x55, 0x82, 0xa5, 0xa4,
+  0xa8, 0x2a, 0x0a, 0x82, 0xa0, 0xa8, 0xd8, 0xd4,
+  0x52, 0x14, 0x00, 0xad, 0x42, 0xa0, 0xa8, 0x2a,
+  0x0a, 0x9f, 0x59, 0x41, 0x5c, 0x2a, 0x0a, 0x87,
+  0x9e, 0x72, 0x05, 0x58, 0x2b, 0x82, 0x80, 0x4d,
+  0x24, 0x2a, 0x0a, 0x82, 0xa0, 0xa8, 0x2a, 0x1e,
+  0x6a, 0x29, 0x0a, 0xf0, 0x53, 0x60, 0xa8, 0x2a,
+  0x0a, 0x82, 0xa0, 0xa8, 0x79, 0xa8, 0xd8, 0x2a,
+  0xc1, 0x5f, 0x0a, 0x95, 0x8a, 0x82, 0xa0, 0xa9,
+  0x3c, 0xa8, 0x2a, 0x92, 0xc2, 0x0a, 0x82, 0xa0,
+  0xa8, 0x2a, 0x28, 0x3e, 0x67, 0x85, 0x69, 0x1a,
+  0x41, 0xa6, 0x82, 0x80, 0x15, 0x70, 0xa9, 0x61,
+  0x50, 0x54, 0x15, 0x27, 0x95, 0x05, 0x52, 0x58,
+  0x41, 0x50, 0x54, 0x29, 0xe9, 0x3c, 0x2b, 0xc3,
+  0x42, 0x34, 0xc0, 0xa8, 0x2a, 0x0a, 0x82, 0xa0,
+  0xa8, 0x2a, 0x14, 0xd9, 0x52, 0x14, 0x21, 0x4c,
+  0x0a, 0xf8, 0x54, 0x15, 0x05, 0x41, 0x50, 0x25,
+  0xf5, 0x42, 0xae, 0x15, 0x05, 0x41, 0x50, 0x54,
+  0x30, 0xbe, 0xf8, 0x55, 0xc2, 0xa4, 0xc2, 0xa0,
+  0xa8, 0x2a, 0x00, 0x5a, 0x6a, 0x15, 0x05, 0x41,
+  0x50, 0x54, 0x15, 0x0a, 0x6a, 0x1a, 0x0a, 0xb0,
+  0x56, 0xa1, 0x50, 0xab, 0xf5, 0xb4, 0x39, 0x3c,
+  0xf7, 0x62, 0x9c, 0x5c, 0x46, 0xda, 0x52, 0x3c,
+  0xcd, 0xbb, 0x3d, 0x68, 0xe8, 0x61, 0x18, 0xc4,
+  0x7b, 0x1b, 0xf3, 0x30, 0x0f, 0x3e, 0xed, 0x56,
+  0x6b, 0xb0, 0xea, 0xf2, 0xd9, 0x94, 0x29, 0x5b,
+  0x85, 0xbb, 0xc9, 0x1b, 0xd2, 0x67, 0xcf, 0xfa,
+  0xe5, 0x4a, 0x72, 0x6a, 0xf3, 0xbc, 0xac, 0x2a,
+  0x7b, 0xc9, 0xc2, 0x74, 0xef, 0x6d, 0x87, 0x4e,
+  0x5d, 0xee, 0xa5, 0x11, 0xe2, 0x73, 0x61, 0xbb,
+  0x8f, 0xcf, 0xeb, 0x78, 0x3b, 0x0a, 0xd0, 0x74,
+  0x52, 0x88, 0x46, 0x94, 0x26, 0x02, 0x9d, 0x3f,
+  0x0f, 0x7f, 0x7a, 0x80, 0xe9, 0xb8, 0x4e, 0x97,
+  0x8e, 0x42, 0xd2, 0x48, 0x74, 0x98, 0x74, 0xec,
+  0xdc, 0x77, 0x91, 0x26, 0x22, 0xb6, 0x41, 0xe1,
+  0xed, 0xe1, 0xf3, 0xff, 0xed, 0x57, 0x47, 0x08,
+  0xf0, 0x15, 0xc1, 0x08, 0x4e, 0x87, 0xb3, 0x66,
+  0xf6, 0x85, 0x02, 0x16, 0x7a, 0x14, 0x2d, 0x12,
+  0x75, 0x2a, 0x7f, 0xf0, 0xb8, 0xba, 0xf4, 0xfe,
+  0x5f, 0xdf, 0xbf, 0xae, 0x1d, 0x3f, 0x3f, 0xfe,
+  0x7d, 0xb0, 0xe9, 0xf5, 0x1e, 0x15, 0x79, 0xd0,
+  0x27, 0xa9, 0xf2, 0xd9, 0xff, 0x59, 0x44, 0x1f,
+  0xc0, 0xf0, 0x0e, 0x9d, 0x98, 0xd1, 0xd2, 0xcb,
+  0x1e, 0xb8, 0x0f, 0x27, 0x98, 0xb9, 0x41, 0xd3,
+  0xec, 0x6d, 0xf5, 0xa4, 0xe8, 0xf1, 0xe5, 0x54,
+  0x86, 0x79, 0x7f, 0x74, 0x3a, 0x4b, 0x89, 0x95,
+  0xfd, 0xe2, 0xee, 0x3b, 0x84, 0x53, 0xda, 0xf0,
+  0xbc, 0xe9, 0xe5, 0xd5, 0xbb, 0xa9, 0x53, 0xe7,
+  0xb8, 0x21, 0x09, 0xd1, 0xf3, 0xcf, 0xd4, 0x9e,
+  0x36, 0x44, 0x9e, 0x38, 0x43, 0x15, 0x56, 0x02,
+  0x3b, 0x1d, 0x61, 0xb1, 0x3f, 0x0e, 0xa0, 0xcf,
+  0xa1, 0xd3, 0xfd, 0x47, 0xf1, 0xf6, 0xc0, 0x54,
+  0xe9, 0xed, 0xb6, 0x56, 0xc7, 0x4f, 0xff, 0x96,
+  0xca, 0xc4, 0x5b, 0xe0, 0xa7, 0x72, 0x1a, 0x2f,
+  0x89, 0xfc, 0x1e, 0xbd, 0x57, 0x28, 0x3a, 0x7f,
+  0xfe, 0xcb, 0xef, 0x7a, 0xb6, 0xf7, 0xc0, 0x3e,
+  0x56, 0x61, 0x53, 0x5f, 0x0e, 0x9f, 0x0f, 0xa8,
+  0xe6, 0x1a, 0x61, 0x39, 0xeb, 0xea, 0xbc, 0x69,
+  0x84, 0xe6, 0x02, 0x9a, 0x81, 0x39, 0xfd, 0xfe,
+  0xd3, 0x75, 0x10, 0x1a, 0x81, 0x39, 0xfd, 0x5c,
+  0xb7, 0xab, 0xad, 0x06, 0x98, 0x4e, 0x6c, 0xd8,
+  0xd3, 0x09, 0xcc, 0x10, 0x9e, 0x61, 0x38, 0xc4,
+  0xd3, 0x29, 0x34, 0xf1, 0x73, 0x08, 0xaa, 0x80,
+  0xd9, 0x08, 0x24, 0x72, 0xb9, 0x66, 0x13, 0x38,
+  0xf9, 0xe5, 0xea, 0x53, 0xf7, 0x0c, 0x79, 0x11,
+  0x55, 0x50, 0xb7, 0x94, 0xa9, 0x0a, 0xae, 0x73,
+  0x63, 0x94, 0x25, 0xb2, 0xdd, 0xe5, 0x5b, 0xcf,
+  0xb6, 0xc1, 0xf6, 0x93, 0xa7, 0xdf, 0xcd, 0xf8,
+  0xd1, 0xd3, 0xfd, 0x6e, 0x65, 0xbc, 0xb4, 0xbc,
+  0xe9, 0xfb, 0x7f, 0xdf, 0xb9, 0xd4, 0x1d, 0x1e,
+  0x3e, 0xc0, 0x1c, 0xc7, 0xd1, 0x6f, 0x78, 0x4a,
+  0xc2, 0xae, 0x91, 0x64, 0xbc, 0x8f, 0x29, 0x74,
+  0x38, 0x27, 0xff, 0x32, 0xf5, 0xf7, 0xe9, 0x7d,
+  0xfd, 0x5f, 0x1d, 0x3f, 0xff, 0xbf, 0x94, 0xe5,
+  0x7b, 0xf6, 0xf2, 0xde, 0xda, 0xf3, 0x0e, 0x9f,
+  0xbf, 0xab, 0x3d, 0x65, 0x3a, 0x7f, 0xfd, 0xdf,
+  0xbf, 0x75, 0xbe, 0xb7, 0xa8, 0x72, 0xc7, 0x4e,
+  0x1a, 0xd4, 0xf1, 0x01, 0xcf, 0xff, 0x6f, 0x15,
+  0xb2, 0xe8, 0xc1, 0x4e, 0xe4, 0x34, 0x40, 0x6e,
+  0x35, 0x10, 0x04, 0x72, 0xdd, 0xee, 0x31, 0x33,
+  0x6f, 0x46, 0x27, 0x3f, 0xff, 0xb9, 0xf9, 0x5f,
+  0x08, 0xf9, 0x9b, 0xef, 0x6c, 0x0d, 0xce, 0x9f,
+  0xff, 0xee, 0x7e, 0x7d, 0xa7, 0xe5, 0x2f, 0xde,
+  0xa0, 0x70, 0x42, 0x12, 0xa2, 0xc8, 0xcb, 0xfb,
+  0x0c, 0xfe, 0x5c, 0x14, 0xee, 0x43, 0x44, 0x13,
+  0x3f, 0xcb, 0x7c, 0x14, 0xee, 0x43, 0x45, 0xf3,
+  0x3e, 0xf3, 0x6f, 0xe5, 0x76, 0x3f, 0xa4, 0x3a,
+  0x9f, 0xf5, 0x1d, 0x4e, 0xe6, 0x5f, 0xfc, 0xd8,
+  0xe9, 0xc1, 0x08, 0x4a, 0x9f, 0xaf, 0x6c, 0x4e,
+  0x12, 0x9c, 0x5e, 0x45, 0x08, 0x99, 0xfb, 0x04,
+  0xff, 0xd4, 0x31, 0x69, 0xaf, 0xf2, 0x8d, 0xef,
+  0x3a, 0x7f, 0xfb, 0x7d, 0x3f, 0xd0, 0x96, 0xf0,
+  0x00, 0xa2, 0xf3, 0xa7, 0x04, 0x21, 0x2a, 0x7f,
+  0x6f, 0x02, 0xff, 0x29, 0xb9, 0x4e, 0x2f, 0x27,
+  0xff, 0xe6, 0xef, 0x42, 0x5b, 0xdb, 0x6d, 0x81,
+  0xd1, 0x7a, 0xe5, 0x07, 0x4b, 0xac, 0x8a, 0xbd,
+  0x51, 0x21, 0xea, 0xa2, 0xfd, 0x0d, 0xa1, 0x24,
+  0x62, 0x4d, 0xe3, 0x1b, 0x9f, 0x5b, 0x2e, 0xd3,
+  0xce, 0x9f, 0xf6, 0x5d, 0x46, 0xb6, 0x5f, 0xdc,
+  0xf1, 0x04, 0x4f, 0xe5, 0xc1, 0x4e, 0xe4, 0x34,
+  0x41, 0x0e, 0x3c, 0x99, 0xfb, 0xac, 0x23, 0xe0,
+  0x9d, 0x3f, 0x6e, 0xf6, 0x0f, 0x7d, 0xe7, 0x47,
+  0xcf, 0x77, 0x52, 0xb8, 0xb2, 0x67, 0x80, 0x71,
+  0xfc, 0x2a, 0x27, 0xf9, 0x7f, 0x7d, 0xf9, 0x6e,
+  0xa4, 0xe9, 0xff, 0xee, 0x0d, 0xf2, 0xcb, 0xeb,
+  0xff, 0x2d, 0xe3, 0xa1, 0xe8, 0x88, 0xf9, 0xd4,
+  0xfe, 0xbe, 0xf6, 0x54, 0x3d, 0x49, 0xd3, 0xde,
+  0x6b, 0xc1, 0x3a, 0x7f, 0xfd, 0xad, 0x1f, 0x5c,
+  0xb3, 0x96, 0xf9, 0x6d, 0x44, 0xe9, 0xf6, 0x5e,
+  0xbb, 0xeb, 0xb1, 0xfc, 0xef, 0x23, 0x9f, 0x92,
+  0xde, 0xdc, 0xf6, 0x93, 0xa7, 0xe6, 0x2e, 0xee,
+  0xd9, 0x41, 0xd3, 0xff, 0xff, 0xde, 0xbf, 0x33,
+  0xbe, 0x07, 0xfa, 0xba, 0xb2, 0xde, 0x5b, 0xdb,
+  0x5e, 0x61, 0xd1, 0xb2, 0x38, 0xfc, 0x65, 0xc6,
+  0x33, 0x87, 0x7d, 0x4e, 0x9f, 0xf7, 0x7d, 0x30,
+  0x53, 0xb9, 0x0d, 0x10, 0x8c, 0x29, 0xf1, 0x6a,
+  0x3b, 0x3f, 0xf9, 0x72, 0x9d, 0xf7, 0xf7, 0xf5,
+  0x7e, 0x54, 0xe9, 0xff, 0xee, 0xea, 0x37, 0xe5,
+  0xb9, 0x8e, 0x08, 0x42, 0x74, 0xb3, 0x64, 0x4f,
+  0x34, 0x9b, 0x38, 0x21, 0x09, 0x53, 0xfd, 0x80,
+  0xe1, 0xc6, 0xd9, 0xb1, 0x4e, 0x2f, 0x26, 0x08,
+  0x4a, 0x9c, 0x10, 0x84, 0xa9, 0xfb, 0xa8, 0xda,
+  0xcb, 0x52, 0x9c, 0x5e, 0x47, 0xd1, 0x6c, 0x14,
+  0x7d, 0xc3, 0x29, 0xf2, 0x7b, 0x6d, 0xec, 0x29,
+  0xc6, 0xce, 0x70, 0x42, 0x12, 0xa7, 0x55, 0x44,
+  0xa7, 0x17, 0x92, 0x07, 0x8f, 0xfe, 0xea, 0xd3,
+  0xf6, 0xdf, 0x57, 0xf2, 0x1d, 0x3f, 0xb7, 0x8e,
+  0xde, 0x6c, 0xbb, 0x1d, 0x3f, 0xaf, 0x6c, 0x6d,
+  0x97, 0xa9, 0xd0, 0x28, 0x98, 0xb1, 0x67, 0xce,
+  0x21, 0x51, 0xdf, 0x90, 0xc0, 0x9d, 0x4e, 0xeb,
+  0x9b, 0xa9, 0xd3, 0xff, 0xb3, 0x77, 0xdf, 0x06,
+  0x22, 0xd9, 0x58, 0x74, 0xfc, 0x9e, 0xad, 0xbc,
+  0xd1, 0x53, 0xfb, 0xf9, 0x4b, 0xeb, 0xed, 0x27,
+  0x4f, 0x77, 0x0e, 0x93, 0xa3, 0x41, 0xeb, 0xd0,
+  0x6d, 0x3c, 0xbc, 0xc6, 0xc5, 0x4e, 0x08, 0x42,
+  0x54, 0xff, 0xf6, 0xf5, 0x06, 0x67, 0xef, 0x6f,
+  0x2f, 0xe8, 0x29, 0xc5, 0xe4, 0xb1, 0x11, 0x3c,
+  0xc3, 0xe8, 0x54, 0xf9, 0x1e, 0x57, 0x4a, 0x57,
+  0xa1, 0x0b, 0x68, 0x61, 0xcf, 0xff, 0x99, 0x88,
+  0xbf, 0xeb, 0xd7, 0x6d, 0x78, 0x5e, 0x74, 0xf9,
+  0x6f, 0x56, 0xd8, 0x74, 0x29, 0xfe, 0x5d, 0x52,
+  0x7f, 0xfb, 0xcd, 0xb3, 0xfb, 0x7f, 0x83, 0x9f,
+  0xed, 0x27, 0x4f, 0xff, 0xf6, 0xd6, 0xf0, 0x71,
+  0xbf, 0xcc, 0xeb, 0xd7, 0x57, 0xe5, 0x37, 0x3a,
+  0x31, 0x18, 0x1c, 0xa7, 0x0a, 0xd9, 0x0a, 0xd0,
+  0x9a, 0xf8, 0xe5, 0xf6, 0x87, 0xa6, 0x4b, 0x28,
+  0xf4, 0x72, 0x4d, 0x42, 0xf8, 0x48, 0xd9, 0x0a,
+  0xfb, 0x46, 0x4e, 0x08, 0x49, 0x7e, 0x18, 0x15,
+  0x95, 0x3b, 0x79, 0x41, 0x5a, 0xc3, 0x44, 0x30,
+  0xe1, 0x9c, 0xd9, 0x7e, 0x74, 0xff, 0xf6, 0x7d,
+  0xd7, 0xd3, 0xea, 0x6b, 0x6c, 0x07, 0x1d, 0x2a,
+  0x5e, 0x7d, 0xfb, 0x0e, 0xcf, 0xd6, 0x6b, 0xd6,
+  0xf3, 0x0e, 0x9f, 0xf7, 0xd6, 0xf6, 0xe0, 0x75,
+  0x35, 0x3a, 0x73, 0x5a, 0x89, 0xd3, 0xfe, 0xef,
+  0x0e, 0x52, 0xe0, 0x84, 0x27, 0x47, 0x1e, 0xdd,
+  0x47, 0x67, 0xff, 0xbe, 0xaf, 0xd1, 0xbe, 0xfe,
+  0xfe, 0xaf, 0xca, 0x9d, 0x18, 0x99, 0xf2, 0x17,
+  0xda, 0x13, 0x20, 0x21, 0x9f, 0xcb, 0xf7, 0xff,
+  0x30, 0x07, 0x4f, 0xe7, 0xe0, 0xd7, 0xeb, 0x41,
+  0xd3, 0xff, 0xca, 0xd9, 0x45, 0xdb, 0xef, 0xfc,
+  0xa3, 0xc2, 0x7b, 0xbd, 0xe7, 0xff, 0xb2, 0xeb,
+  0xf4, 0xcb, 0xdb, 0xc2, 0x04, 0x3a, 0x7d, 0xd5,
+  0xcf, 0xdc, 0xe9, 0xd7, 0xed, 0xd9, 0xd3, 0xfa,
+  0xf6, 0xf3, 0x81, 0xde, 0x3a, 0x28, 0x4c, 0x8f,
+  0x65, 0xff, 0xa6, 0x5c, 0x9b, 0x51, 0xf9, 0xfd,
+  0xa8, 0x16, 0xde, 0xe7, 0x9d, 0x3f, 0xff, 0x7f,
+  0x2b, 0xae, 0x8c, 0xb7, 0x7f, 0x1a, 0x7a, 0xd2,
+  0x74, 0xff, 0xb2, 0xba, 0xe0, 0xa7, 0x72, 0x1a,
+  0x20, 0x69, 0xf6, 0x5e, 0xdc, 0xfd, 0x08, 0xa5,
+  0xfa, 0xf4, 0xff, 0xff, 0xfd, 0x97, 0xb7, 0x7f,
+  0x4e, 0x8a, 0x8f, 0x75, 0xdb, 0x66, 0xda, 0x31,
+  0x9d, 0xfa, 0x5e, 0x78, 0x82, 0xe7, 0xfd, 0xdd,
+  0xa5, 0x3b, 0x6d, 0x1a, 0x42, 0x78, 0x82, 0xe7,
+  0xfe, 0xb7, 0xad, 0xe5, 0xfd, 0xf4, 0x69, 0x09,
+  0xe2, 0x0b, 0x9f, 0xcb, 0xef, 0xdf, 0x46, 0x90,
+  0x9e, 0x20, 0xb9, 0xf9, 0x99, 0xb6, 0x8d, 0x21,
+  0x3c, 0x41, 0x73, 0xff, 0xfd, 0xdf, 0xff, 0x99,
+  0xa2, 0xa9, 0x6f, 0x0f, 0xb4, 0xd1, 0x81, 0x3c,
+  0x41, 0x73, 0x53, 0xa3, 0x64, 0xe8, 0x51, 0x40,
+  0x55, 0xb9, 0x13, 0xe7, 0xf1, 0x65, 0x52, 0xdf,
+  0x94, 0x7d, 0x3d, 0xc2, 0x0e, 0x3a, 0x7f, 0xeb,
+  0x7a, 0xde, 0x5f, 0xdf, 0x46, 0x90, 0x9e, 0x20,
+  0xb9, 0xfe, 0x6a, 0xa9, 0xea, 0x34, 0x69, 0x09,
+  0xe2, 0x0b, 0x9f, 0x5e, 0xaa, 0xcd, 0x08, 0x8a,
+  0x2d, 0xea, 0xd3, 0xff, 0xb4, 0x25, 0xbc, 0x8b,
+  0x7a, 0xe8, 0xd2, 0x13, 0xc4, 0x17, 0x3f, 0xff,
+  0xf7, 0xff, 0xe6, 0x68, 0xd7, 0x34, 0x55, 0x2d,
+  0xe1, 0xf6, 0x9a, 0x30, 0x27, 0x88, 0x2e, 0x31,
+  0x32, 0x6a, 0x50, 0xf9, 0x72, 0x7f, 0xad, 0xe1,
+  0xf6, 0x9a, 0x30, 0x27, 0x88, 0x2e, 0x7f, 0xfb,
+  0xba, 0x97, 0xd6, 0xde, 0xdb, 0x65, 0x15, 0x2a,
+  0x7f, 0xd8, 0xf7, 0xeb, 0x51, 0xfd, 0x1b, 0x87,
+  0x88, 0x2e, 0x11, 0x1d, 0x02, 0x91, 0x55, 0x09,
+  0xff, 0x27, 0x86, 0xfc, 0x0a, 0xe8, 0x09, 0xe2,
+  0x0b, 0x9f, 0xad, 0xeb, 0x5b, 0xc0, 0x34, 0x01,
+  0x73, 0xec, 0x06, 0x8d, 0x21, 0x3c, 0x41, 0x73,
+  0x65, 0xd0, 0xfc, 0xec, 0x77, 0x14, 0xa3, 0xae,
+  0xb0, 0xbf, 0x9f, 0x99, 0x9b, 0x68, 0xd2, 0x13,
+  0xc4, 0x17, 0x3f, 0xe4, 0xb7, 0x87, 0xda, 0x68,
+  0xc0, 0x9e, 0x20, 0xb9, 0xb3, 0x47, 0x22, 0x32,
+  0xa7, 0xf3, 0xfb, 0x5f, 0x33, 0xbf, 0x4b, 0xcf,
+  0x10, 0x5c, 0xff, 0xb3, 0xcd, 0xb3, 0xf9, 0xb7,
+  0x3c, 0xf1, 0x05, 0xb0, 0xf0, 0xa3, 0x65, 0xdc,
+  0x70, 0x16, 0x7e, 0x3e, 0x7a, 0xc6, 0x31, 0x78,
+  0xc6, 0x75, 0x85, 0xa8, 0x5c, 0x67, 0xc0, 0xa8,
+  0x00, 0xa6, 0x88, 0x2d, 0xc8, 0x80, 0x9f, 0xf6,
+  0x3e, 0xdc, 0xf6, 0xf6, 0xfd, 0x68, 0x3a, 0x7f,
+  0x0f, 0xf3, 0x6b, 0x6a, 0x13, 0xa7, 0xd4, 0xdf,
+  0x84, 0x07, 0x4f, 0xd9, 0x47, 0x59, 0x77, 0x67,
+  0x47, 0x91, 0x17, 0xc6, 0x9f, 0x27, 0x9d, 0xc3,
+  0x41, 0xd3, 0x01, 0x4e, 0x9e, 0xf2, 0xb3, 0x0e,
+  0x83, 0xa7, 0xee, 0xd3, 0x75, 0x10, 0x1d, 0x1b,
+  0x1b, 0x7f, 0x85, 0x4f, 0xff, 0xe5, 0xf6, 0xdf,
+  0x5d, 0x52, 0xf8, 0x9b, 0x2a, 0x6f, 0x61, 0xd3,
+  0x01, 0x4e, 0x99, 0x74, 0x9d, 0x3f, 0xd9, 0x7a,
+  0xab, 0x37, 0xe3, 0x47, 0x4f, 0xea, 0xe5, 0xbd,
+  0x5d, 0x68, 0x3a, 0x60, 0x84, 0xa9, 0xfe, 0xfe,
+  0x36, 0xe7, 0xd7, 0xdb, 0x1d, 0x08, 0x9f, 0xbf,
+  0x86, 0xc4, 0x55, 0x8a, 0xf6, 0x22, 0x03, 0x13,
+  0x76, 0x2b, 0xf1, 0x7a, 0x9d, 0x04, 0xd7, 0x78,
+  0xb4, 0xe0, 0x84, 0x25, 0x49, 0x85, 0x38, 0xbc,
+  0x9f, 0x73, 0x5d, 0xc2, 0x53, 0x91, 0xb3, 0xbe,
+  0x17, 0x53, 0xfa, 0x9b, 0xae, 0x5b, 0x28, 0x3a,
+  0x15, 0xb2, 0x07, 0xc8, 0xda, 0x34, 0xa0, 0xd2,
+  0x63, 0xe8, 0xd5, 0x45, 0x3a, 0xd0, 0xd8, 0xea,
+  0x48, 0xf7, 0xd1, 0xab, 0x0d, 0x1d, 0x65, 0x7f,
+  0xb6, 0x4b, 0x9e, 0xc4, 0x5b, 0x9d, 0x3d, 0x8c,
+  0xcb, 0x9d, 0x3d, 0xd4, 0x6f, 0x79, 0xd0, 0xa7,
+  0xc7, 0x48, 0xfb, 0x79, 0x04, 0xfd, 0xfd, 0x76,
+  0x67, 0x3c, 0xe9, 0xff, 0xea, 0x5f, 0xf5, 0xd0,
+  0xcf, 0xae, 0x9b, 0xfa, 0x83, 0xa7, 0xf5, 0x6e,
+  0xdb, 0x3f, 0x9b, 0x1d, 0x0a, 0x8b, 0xaf, 0x17,
+  0xf2, 0xb4, 0xee, 0xd1, 0xbc, 0xe9, 0xff, 0xef,
+  0xbf, 0x46, 0x6d, 0xea, 0xd3, 0x7d, 0x7a, 0xa7,
+  0x46, 0x83, 0xf4, 0xc1, 0xf9, 0xfa, 0x86, 0x9e,
+  0xdc, 0x1a, 0x0e, 0x99, 0xf4, 0x1d, 0x3e, 0xb6,
+  0x79, 0xf5, 0x3a, 0x7f, 0xfa, 0xcb, 0xbd, 0xd7,
+  0xff, 0x02, 0xb5, 0x50, 0x15, 0x3f, 0x81, 0x82,
+  0x9d, 0xc8, 0x78, 0x81, 0x21, 0xe8, 0xb3, 0xd8,
+  0x9c, 0x54, 0x66, 0x6f, 0x79, 0xd3, 0xd7, 0xa3,
+  0xbe, 0x74, 0xf5, 0x35, 0xeb, 0x9d, 0x14, 0x1e,
+  0xee, 0x0c, 0xd8, 0x8a, 0x7f, 0x7f, 0x83, 0x5a,
+  0xa8, 0x0e, 0x9c, 0x10, 0x84, 0xf8, 0x7d, 0x4e,
+  0xef, 0xec, 0x5c, 0x3e, 0x8e, 0x35, 0x31, 0xb2,
+  0x25, 0x40, 0xb7, 0x3f, 0xfe, 0xcf, 0xfb, 0x4b,
+  0xab, 0x7b, 0x6b, 0xcf, 0x7a, 0x9d, 0x14, 0x1f,
+  0xe6, 0x92, 0x48, 0xdd, 0x4a, 0xbc, 0x1e, 0x69,
+  0x90, 0xca, 0xf4, 0x23, 0x7a, 0x34, 0x09, 0xf7,
+  0xae, 0xb7, 0xa9, 0x53, 0xc8, 0xb7, 0xa9, 0x53,
+  0x04, 0x25, 0x43, 0xcf, 0x77, 0x09, 0xc2, 0x41,
+  0x36, 0x04, 0xa7, 0x1a, 0xe9, 0xff, 0xf6, 0x5d,
+  0x53, 0x33, 0xf7, 0xb7, 0x97, 0xf4, 0x1d, 0x00,
+  0x3f, 0x80, 0x92, 0xcf, 0xff, 0xe5, 0x6d, 0xef,
+  0x83, 0x45, 0xeb, 0x89, 0x6e, 0xfd, 0xea, 0x74,
+  0xfe, 0x6a, 0x97, 0xdb, 0x55, 0x13, 0xa7, 0x3f,
+  0x84, 0xe9, 0xf3, 0xf2, 0xf9, 0xb1, 0x52, 0xf3,
+  0x47, 0x83, 0x71, 0xa9, 0x80, 0xa7, 0x4c, 0x05,
+  0x3a, 0x7e, 0xfe, 0xaf, 0xcf, 0xbb, 0xc6, 0xa8,
+  0x02, 0xb3, 0xff, 0x5e, 0xd8, 0xcd, 0xea, 0x0c,
+  0xa6, 0xe7, 0x4f, 0xea, 0x53, 0xc3, 0xbd, 0x76,
+  0x3a, 0x78, 0x0c, 0xe7, 0xd4, 0xfe, 0xee, 0x8d,
+  0x3b, 0x73, 0x29, 0x3a, 0x14, 0xf6, 0x38, 0xe6,
+  0x7a, 0xba, 0xd3, 0x73, 0xa7, 0x04, 0x21, 0x2a,
+  0x7d, 0x9a, 0x7f, 0xad, 0x4a, 0x71, 0x79, 0x3e,
+  0xc7, 0x04, 0x21, 0x3a, 0x14, 0xf8, 0x2e, 0x73,
+  0x3c, 0x1e, 0xfb, 0xce, 0x99, 0x2c, 0x74, 0xe0,
+  0x84, 0x25, 0x4f, 0xde, 0xed, 0x36, 0xf5, 0xca,
+  0x71, 0x79, 0x3e, 0xc0, 0x66, 0x34, 0x74, 0xab,
+  0xa1, 0x12, 0xa2, 0x63, 0xf3, 0xe9, 0xef, 0x7f,
+  0x57, 0xec, 0x8e, 0xdc, 0x85, 0xb4, 0x2a, 0xe3,
+  0xb3, 0xc8, 0xb1, 0x93, 0x4b, 0xb0, 0xa9, 0xda,
+  0x31, 0x8e, 0x20, 0xac, 0x28, 0x2f, 0x18, 0x74,
+  0xfc, 0xac, 0x11, 0xeb, 0x9d, 0x3f, 0xfd, 0xe6,
+  0x52, 0xfa, 0xe8, 0xcf, 0xff, 0x3c, 0x03, 0xa2,
+  0xc7, 0xfb, 0x72, 0xa9, 0x39, 0xba, 0x42, 0x19,
+  0xe5, 0x65, 0x76, 0xd1, 0x19, 0x1b, 0xe5, 0x26,
+  0xed, 0x2c, 0x07, 0x2b, 0x74, 0xad, 0x31, 0xb8,
+  0xa4, 0x76, 0x54, 0xca, 0xa7, 0xf4, 0x27, 0x5a,
+  0x9e, 0x7f, 0x19, 0xd3, 0x56, 0x4a, 0x0b, 0xb4,
+  0xf8, 0x57, 0x53, 0xcb, 0x41, 0x2c, 0xe7, 0xf3,
+  0xac, 0x15, 0xac, 0x97, 0xaf, 0x59, 0xcf, 0xeb,
+  0x19, 0xab, 0x68, 0x76, 0x06, 0x14, 0x5b, 0x92,
+  0xc4, 0xf7, 0xce, 0xec, 0xb7, 0xc6, 0x1b, 0x0e,
+  0x84, 0x47, 0x03, 0xf1, 0x0d, 0x8b, 0x3f, 0x9d,
+  0x82, 0x9d, 0xc8, 0x68, 0xb8, 0xe7, 0xf3, 0xb0,
+  0x53, 0xb9, 0x0d, 0x17, 0x5c, 0xff, 0xce, 0xe7,
+  0xbb, 0x05, 0x3b, 0x90, 0xd1, 0x28, 0xc2, 0xc2,
+  0x30, 0xd5, 0xe5, 0x1b, 0x1d, 0xe9, 0x3b, 0x43,
+  0xbf, 0x43, 0xc3, 0x76, 0x81, 0xd8, 0x89, 0x32,
+  0xa9, 0xc5, 0xce, 0xdb, 0xce, 0xe7, 0xff, 0x39,
+  0x9c, 0xf7, 0x60, 0xa7, 0x72, 0x1a, 0x25, 0xa9,
+  0xf0, 0xa7, 0x72, 0x1a, 0x23, 0x79, 0xff, 0x73,
+  0xdd, 0x82, 0x9d, 0xc8, 0x68, 0x97, 0xe4, 0xec,
+  0x3f, 0x66, 0x18, 0x4f, 0xe7, 0x60, 0xa7, 0x72,
+  0x1a, 0x2a, 0xb9, 0xfe, 0xd3, 0x9f, 0xca, 0x6f,
+  0xcc, 0x3a, 0x6d, 0xbc, 0x74, 0xfd, 0x82, 0x9d,
+  0xc8, 0x68, 0x90, 0x23, 0x41, 0xe6, 0x38, 0x5e,
+  0x7d, 0x5e, 0xff, 0x52, 0x74, 0x3c, 0xf2, 0xe9,
+  0x24, 0x8d, 0x28, 0xf4, 0xe8, 0x68, 0xcf, 0xfd,
+  0xfc, 0xa1, 0xdb, 0x8b, 0xff, 0xe5, 0xce, 0x87,
+  0x1f, 0x80, 0x94, 0xcf, 0xe7, 0x60, 0xa7, 0x72,
+  0x1a, 0x2c, 0x89, 0xfc, 0xec, 0x14, 0xee, 0x43,
+  0x45, 0xaf, 0x3f, 0x9d, 0x82, 0x9d, 0xc8, 0x68,
+  0xb9, 0x27, 0xc2, 0x9d, 0xc8, 0x68, 0xbb, 0x27,
+  0xfd, 0xcf, 0x76, 0x0a, 0x77, 0x21, 0xa2, 0x8e,
+  0x93, 0xb0, 0xfd, 0x98, 0x61, 0x3e, 0x14, 0xee,
+  0x43, 0x45, 0x2b, 0x3f, 0xff, 0xfd, 0x65, 0xa1,
+  0x6d, 0xe6, 0xdd, 0xb5, 0xbc, 0xe4, 0xb7, 0x9a,
+  0xb2, 0xd1, 0x87, 0x4f, 0x9c, 0xce, 0x7b, 0xb1,
+  0x16, 0x4d, 0x18, 0x45, 0x0b, 0x9d, 0xef, 0x86,
+  0x45, 0x24, 0xfe, 0x8e, 0x7d, 0x84, 0x20, 0x3b,
+  0xa9, 0xdd, 0xe1, 0x62, 0xda, 0x1b, 0x33, 0xfc,
+  0xf7, 0x60, 0xa7, 0x72, 0x1a, 0x23, 0x89, 0xfe,
+  0xf3, 0xb0, 0x53, 0xb9, 0x0d, 0x15, 0xac, 0x9d,
+  0xc8, 0x82, 0xba, 0x0c, 0xff, 0xe7, 0x33, 0x9e,
+  0xec, 0x14, 0xee, 0x43, 0x44, 0xb7, 0x36, 0x52,
+  0x74, 0xfe, 0xdb, 0x18, 0xc5, 0xf5, 0x4e, 0x8a,
+  0x4f, 0x27, 0xc2, 0xd3, 0xad, 0xb3, 0xce, 0x9c,
+  0xf6, 0x21, 0xd3, 0xff, 0xf5, 0xba, 0x90, 0x6d,
+  0x6e, 0x7e, 0x57, 0xfa, 0xf6, 0xf3, 0xa0, 0xd1,
+  0x0d, 0xcf, 0xfb, 0x9e, 0xec, 0x14, 0xee, 0x43,
+  0x44, 0xc1, 0x38, 0x75, 0x01, 0x53, 0xfb, 0xf9,
+  0x7b, 0xa8, 0xd4, 0xe9, 0x39, 0x53, 0x64, 0xa0,
+  0x8f, 0x61, 0xdc, 0x1b, 0x45, 0xf6, 0x0b, 0xdd,
+  0x1b, 0x78, 0xe4, 0xe6, 0x6a, 0x25, 0x4f, 0xfb,
+  0x9e, 0xec, 0x14, 0xee, 0x43, 0x44, 0xc7, 0x27,
+  0x78, 0xf8, 0x98, 0x39, 0x3f, 0x2d, 0x74, 0x5f,
+  0x2c, 0x74, 0xff, 0xff, 0xf3, 0xeb, 0x6c, 0xd4,
+  0x35, 0xb6, 0x26, 0x57, 0x46, 0x52, 0xfa, 0xfb,
+  0xfe, 0x3a, 0x79, 0x3b, 0x90, 0xd1, 0x58, 0xcf,
+  0xfb, 0x73, 0x2f, 0xfc, 0xd5, 0x7f, 0x73, 0xa3,
+  0x4a, 0x63, 0x74, 0x97, 0x0c, 0x20, 0x6e, 0x57,
+  0x3f, 0xf9, 0x7f, 0x7d, 0x3a, 0xaf, 0xf1, 0x14,
+  0x4e, 0x9f, 0xf6, 0x6d, 0x6c, 0xad, 0x2f, 0x5b,
+  0x1d, 0x3f, 0xec, 0xd8, 0x7d, 0xad, 0x00, 0xab,
+  0xce, 0x9f, 0xff, 0xfb, 0xfa, 0xd1, 0x89, 0xa3,
+  0xfa, 0xb7, 0xe8, 0xca, 0x5f, 0x9a, 0xfc, 0x15,
+  0x3a, 0x7f, 0x6e, 0xaa, 0x1a, 0x7b, 0x70, 0x68,
+  0x3a, 0x75, 0xbc, 0xec, 0x4f, 0x31, 0x11, 0x6c,
+  0x93, 0xf3, 0xfb, 0xa0, 0xee, 0x3f, 0x4d, 0xab,
+  0x47, 0x4f, 0xbb, 0xf4, 0x6b, 0x53, 0xa3, 0xe7,
+  0x83, 0x51, 0x89, 0xe5, 0x1e, 0xf9, 0xd3, 0xd5,
+  0xaa, 0x80, 0xe8, 0xb1, 0xe0, 0x04, 0x7e, 0x7c,
+  0xaf, 0x06, 0xaf, 0x3a, 0x72, 0xfd, 0xe7, 0x43,
+  0x47, 0x87, 0x72, 0x89, 0xf9, 0x59, 0x9f, 0xf6,
+  0x93, 0xa5, 0x53, 0xa3, 0xc6, 0xfb, 0x8b, 0xa6,
+  0x02, 0x95, 0x30, 0x42, 0x54, 0x78, 0xd5, 0x84,
+  0x56, 0x7f, 0x73, 0xff, 0x97, 0xb7, 0x8a, 0x71,
+  0xa1, 0x9e, 0xdb, 0xa9, 0xa9, 0xd3, 0x97, 0xed,
+  0x1d, 0x37, 0xd4, 0xe8, 0x68, 0xd8, 0x88, 0xe4,
+  0xf0, 0x83, 0x1b, 0xce, 0x9d, 0xbc, 0x74, 0x9d,
+  0x0a, 0x8b, 0x7c, 0x54, 0xf1, 0x0d, 0x88, 0xe6,
+  0xb5, 0xce, 0x9c, 0x10, 0x84, 0xa9, 0xff, 0xb1,
+  0x36, 0x5a, 0x37, 0xe5, 0xba, 0x92, 0x9c, 0x5e,
+  0x4f, 0x78, 0x5b, 0xf6, 0x3a, 0x42, 0x74, 0xf9,
+  0x9e, 0xb8, 0x38, 0xe8, 0xa0, 0xf6, 0xf7, 0x64,
+  0xba, 0x87, 0xcf, 0xe4, 0xf5, 0x7f, 0x8d, 0xb8,
+  0xe9, 0xb2, 0xe7, 0x45, 0x27, 0x91, 0x63, 0x39,
+  0xeb, 0xff, 0x1e, 0x74, 0xff, 0xef, 0x56, 0xd9,
+  0xb7, 0xf1, 0xb7, 0xf2, 0xa7, 0x40, 0x9f, 0x6d,
+  0xc8, 0x64, 0xe5, 0x5c, 0xd8, 0xd9, 0x8b, 0x19,
+  0x45, 0x85, 0x8d, 0x96, 0x87, 0xcf, 0x1d, 0xfc,
+  0xca, 0xb0, 0xb0, 0xbb, 0xee, 0xf8, 0x48, 0x4f,
+  0x85, 0x3b, 0x90, 0xd1, 0x5b, 0xcf, 0xfb, 0x9e,
+  0xec, 0x14, 0xee, 0x43, 0x44, 0xe1, 0x27, 0x61,
+  0xfb, 0x30, 0xc2, 0x7c, 0x29, 0xdc, 0x86, 0x8b,
+  0x46, 0x7b, 0x1a, 0xf6, 0x93, 0xa4, 0xec, 0x3d,
+  0x4b, 0x18, 0x4f, 0x27, 0x72, 0x1a, 0x2d, 0xa9,
+  0xfa, 0xca, 0xc5, 0xf6, 0xc7, 0x4c, 0xec, 0x13,
+  0xd8, 0xb9, 0x5c, 0xfe, 0x76, 0x0a, 0x77, 0x21,
+  0xa2, 0xe5, 0x9f, 0xce, 0xc1, 0x4e, 0xe4, 0x34,
+  0x5d, 0xb0, 0xac, 0xe5, 0x6a, 0x0a, 0x1f, 0x1f,
+  0xfe, 0xd0, 0xdb, 0xd3, 0x2c, 0x3f, 0xd3, 0xb0,
+  0x9b, 0xb8, 0xc9, 0x6c, 0xf7, 0xf7, 0xfa, 0x96,
+  0x5c, 0xee, 0x7f, 0x3b, 0x05, 0x3b, 0x90, 0xd1,
+  0x53, 0xcf, 0x27, 0x72, 0x1a, 0x2b, 0x99, 0xfc,
+  0xec, 0x14, 0xee, 0x43, 0x45, 0x9d, 0x02, 0x7c,
+  0xd6, 0x2b, 0x9f, 0x0a, 0x77, 0x21, 0xa2, 0x42,
+  0x9f, 0xef, 0x53, 0x5b, 0xfd, 0x59, 0x53, 0xa6,
+  0x7b, 0xb0, 0xfa, 0x80, 0x61, 0x3c, 0xdd, 0x2c,
+  0xac, 0x3a, 0x7f, 0x65, 0xab, 0x5c, 0x1a, 0x0e,
+  0x93, 0xb1, 0x31, 0x1e, 0x84, 0x5d, 0x4b, 0x6e,
+  0x4f, 0x3f, 0xf9, 0xcc, 0xe7, 0xbb, 0x05, 0x3b,
+  0x90, 0xd1, 0x3e, 0x42, 0x2a, 0x4b, 0xdd, 0xc7,
+  0x65, 0x64, 0x79, 0xf0, 0xa7, 0x72, 0x1a, 0x2b,
+  0x29, 0xff, 0x73, 0xdd, 0x82, 0x9d, 0xc8, 0x68,
+  0x9b, 0xa6, 0xf3, 0xb0, 0xfd, 0x98, 0x61, 0x3e,
+  0x14, 0xee, 0x43, 0x44, 0xad, 0x3f, 0xda, 0x6d,
+  0xed, 0x1a, 0xa6, 0x54, 0xe9, 0xf3, 0x99, 0xcf,
+  0x76, 0x1f, 0x6f, 0x18, 0x4f, 0x85, 0x3b, 0x90,
+  0xd1, 0x2e, 0x4f, 0xf7, 0xb9, 0xf7, 0xfa, 0xb2,
+  0xa7, 0x4f, 0x36, 0xf7, 0xd4, 0xe9, 0xf3, 0x99,
+  0xcf, 0x76, 0x22, 0x2e, 0xc6, 0x1c, 0x71, 0x3f,
+  0xf3, 0xb9, 0xee, 0xc1, 0x4e, 0xe4, 0x34, 0x47,
+  0x73, 0xfd, 0x7b, 0x63, 0xdd, 0xdf, 0xa9, 0xd3,
+  0xf3, 0x73, 0xea, 0x99, 0xf3, 0xa7, 0xed, 0xd3,
+  0xf9, 0x6e, 0xb9, 0xd3, 0xe1, 0x4e, 0xe4, 0x34,
+  0x54, 0x33, 0xec, 0xb5, 0xf2, 0x83, 0xa7, 0xff,
+  0xfb, 0x5e, 0xdd, 0xfa, 0x8b, 0x77, 0xae, 0xb6,
+  0xf5, 0xeb, 0x9b, 0x1d, 0x27, 0x6e, 0x89, 0x92,
+  0x37, 0x0b, 0xf0, 0xc6, 0xe6, 0x1b, 0x84, 0xf3,
+  0xe1, 0x4e, 0xe4, 0x34, 0x55, 0x13, 0xfe, 0xe7,
+  0xbb, 0x05, 0x3b, 0x90, 0xd1, 0x35, 0xc9, 0xd8,
+  0x7e, 0xcc, 0x30, 0x9f, 0xce, 0xc1, 0x4e, 0xe4,
+  0x34, 0x55, 0x93, 0xff, 0x3b, 0x9e, 0xec, 0x14,
+  0xee, 0x43, 0x44, 0x89, 0x3e, 0x14, 0xee, 0x43,
+  0x45, 0xa5, 0x3f, 0xee, 0x7b, 0xb0, 0x53, 0xb9,
+  0x0d, 0x13, 0xec, 0x9d, 0x87, 0xec, 0xc3, 0x09,
+  0xff, 0xce, 0x67, 0x3d, 0xd8, 0x29, 0xdc, 0x86,
+  0x8a, 0x12, 0x7d, 0x6f, 0x50, 0xa2, 0x74, 0xf8,
+  0x53, 0xb9, 0x0d, 0x14, 0x7c, 0xff, 0xfd, 0x9b,
+  0x59, 0x77, 0xba, 0xff, 0xe0, 0x56, 0xaa, 0x02,
+  0xa7, 0xce, 0x67, 0x3d, 0xca, 0x8b, 0x4c, 0x27,
+  0xdc, 0x30, 0x85, 0x5e, 0x2c, 0xa2, 0x19, 0x0f,
+  0x4b, 0xc4, 0xcd, 0x31, 0xae, 0x24, 0x34, 0xa9,
+  0x27, 0x68, 0xee, 0xd0, 0xc2, 0x01, 0x3d, 0xe3,
+  0x06, 0x9f, 0xce, 0xc1, 0x4e, 0xe4, 0x34, 0x44,
+  0x53, 0xf6, 0x0a, 0x77, 0x21, 0xa2, 0x2b, 0x9f,
+  0xed, 0xdb, 0xb0, 0x53, 0xb9, 0x0d, 0x15, 0xc4,
+  0x38, 0xfe, 0xb8, 0xd6, 0x7b, 0x2d, 0xd7, 0x3a,
+  0x7f, 0x67, 0x84, 0x00, 0xd6, 0xa7, 0x4b, 0x74,
+  0xf9, 0xe9, 0xd4, 0x82, 0x7f, 0xee, 0xf3, 0xfd,
+  0xfb, 0xeb, 0x61, 0xc3, 0xa7, 0xd9, 0xed, 0x87,
+  0x0e, 0x9d, 0x7a, 0xfa, 0xc7, 0xd5, 0x74, 0x49,
+  0xf0, 0xa7, 0x72, 0x1a, 0x29, 0xe8, 0x6e, 0x23,
+  0xed, 0x61, 0x2f, 0x86, 0x93, 0xff, 0xb9, 0xee,
+  0xdb, 0xfc, 0x1a, 0xd5, 0x40, 0x74, 0x39, 0x10,
+  0x3b, 0x1b, 0xce, 0x76, 0xd8, 0x74, 0xf9, 0x5e,
+  0x0d, 0x5e, 0x74, 0xf2, 0x77, 0x21, 0xa2, 0xb3,
+  0x86, 0x8f, 0x4c, 0x4a, 0x27, 0xea, 0x18, 0xbf,
+  0x7d, 0x4e, 0x9c, 0xb4, 0x78, 0xe9, 0xf5, 0xc1,
+  0xbf, 0xef, 0x3a, 0x76, 0xbd, 0x53, 0xa7, 0xd8,
+  0xd5, 0x1a, 0x80, 0xe9, 0x3b, 0x11, 0xb8, 0x24,
+  0x56, 0x2e, 0xe1, 0xcf, 0x95, 0x6f, 0x1c, 0x9f,
+  0xf9, 0xdc, 0xf7, 0x60, 0xa7, 0x72, 0x1a, 0x24,
+  0x59, 0xfc, 0xec, 0x14, 0xee, 0x43, 0x45, 0x93,
+  0x3f, 0x9d, 0x82, 0x9d, 0xc8, 0x68, 0xb6, 0x27,
+  0x65, 0x70, 0xe9, 0xf0, 0xa7, 0x72, 0x1a, 0x2d,
+  0xb9, 0x39, 0xe7, 0x95, 0x83, 0x53, 0xfe, 0x6e,
+  0x37, 0x37, 0x5a, 0xf6, 0xcf, 0xa8, 0x0e, 0x9f,
+  0x97, 0xef, 0xdb, 0x56, 0x1d, 0x3e, 0x14, 0xee,
+  0x43, 0x45, 0xe1, 0x3d, 0x7d, 0xcc, 0xb1, 0xd3,
+  0xff, 0x2e, 0xf6, 0x52, 0xfb, 0xe7, 0xef, 0x53,
+  0xa7, 0xd9, 0xf0, 0x37, 0xa9, 0xd3, 0xe5, 0xdf,
+  0xaf, 0x54, 0xe9, 0xd7, 0x50, 0x1d, 0x27, 0x6e,
+  0xbc, 0x9c, 0x25, 0x09, 0xb8, 0x5f, 0x49, 0x85,
+  0x89, 0x00, 0x8f, 0xf2, 0x9b, 0x94, 0xce, 0xf6,
+  0x52, 0x74, 0xf8, 0x53, 0xb9, 0x0d, 0x17, 0xa4,
+  0xff, 0xbf, 0xd7, 0x7a, 0xe9, 0xbf, 0xa8, 0x3a,
+  0x7d, 0x8c, 0xb7, 0x6c, 0x74, 0x9d, 0xb2, 0x2d,
+  0x30, 0x73, 0x79, 0x83, 0x7a, 0x0c, 0x2b, 0x22,
+  0x96, 0x88, 0x5a, 0xe4, 0x7e, 0x08, 0x49, 0xe8,
+  0xd2, 0xc5, 0x71, 0x89, 0x80, 0x3b, 0xfc, 0x21,
+  0x75, 0x8e, 0xac, 0x31, 0x9b, 0x4f, 0x65, 0xba,
+  0xe7, 0x4f, 0xec, 0xf0, 0x80, 0x1a, 0xd4, 0xe9,
+  0x6e, 0x9f, 0x3d, 0x3a, 0x90, 0x4f, 0x85, 0x3b,
+  0x90, 0xd1, 0x11, 0xcf, 0xff, 0x5b, 0x5a, 0xd7,
+  0x19, 0xfc, 0x6d, 0xa1, 0x5b, 0xa9, 0xd3, 0xfe,
+  0x7a, 0xd0, 0x39, 0x7b, 0xfa, 0xe7, 0x4f, 0xff,
+  0xf2, 0xdb, 0xbd, 0x75, 0xb7, 0xf2, 0xf6, 0xf5,
+  0xb3, 0xc1, 0x3a, 0x6a, 0x18, 0x54, 0xc1, 0x09,
+  0x53, 0xff, 0x3d, 0xc9, 0x6f, 0x35, 0x65, 0xa1,
+  0xc0, 0x35, 0xa1, 0x17, 0x9f, 0xd9, 0xbb, 0xfe,
+  0x5b, 0xae, 0x74, 0xff, 0xfc, 0x8e, 0x1e, 0xff,
+  0xae, 0xe1, 0x5b, 0xff, 0x80, 0x74, 0x37, 0x15,
+  0x38, 0xe1, 0x6a, 0x18, 0x52, 0xb4, 0x27, 0xdd,
+  0x09, 0x2b, 0xae, 0xb6, 0x35, 0x9f, 0x0a, 0x77,
+  0x21, 0xa2, 0x2e, 0x9f, 0x5c, 0x1b, 0xfe, 0xf2,
+  0xd9, 0xec, 0x93, 0xb0, 0xfa, 0x38, 0xc2, 0x1c,
+  0x98, 0x4b, 0xe1, 0xc7, 0x3f, 0xf3, 0x39, 0xee,
+  0xc1, 0x4e, 0xe4, 0x34, 0x4c, 0xd3, 0xa9, 0x5a,
+  0x9d, 0x39, 0x3c, 0xc3, 0xa7, 0x6e, 0xad, 0xcd,
+  0xd4, 0x74, 0xf9, 0x3a, 0xde, 0x68, 0xe9, 0xff,
+  0x9b, 0xfd, 0x7f, 0x27, 0xb6, 0xbe, 0x21, 0xd3,
+  0xff, 0xfd, 0xaf, 0x7d, 0x3f, 0x9b, 0x5b, 0x5d,
+  0x16, 0x57, 0x8a, 0xd0, 0x74, 0x62, 0x2c, 0x6c,
+  0x8f, 0x3f, 0xfe, 0xdb, 0xdf, 0xa3, 0x2b, 0xee,
+  0xb3, 0x82, 0x10, 0x95, 0x3c, 0x9d, 0xc8, 0x68,
+  0xb3, 0xe7, 0xfd, 0xeb, 0x2b, 0xfd, 0x75, 0xbd,
+  0x4e, 0x9f, 0xfe, 0xf0, 0xdb, 0xb4, 0x63, 0x6f,
+  0xe5, 0x73, 0xe7, 0x4e, 0x08, 0x42, 0x54, 0xff,
+  0xb9, 0xf5, 0xfe, 0x26, 0xd8, 0x25, 0x38, 0xbc,
+  0x9f, 0xe5, 0xb7, 0xb6, 0xff, 0x73, 0x47, 0x4f,
+  0xf7, 0xbf, 0xb6, 0xfd, 0xb5, 0xbd, 0x4e, 0x84,
+  0x4f, 0xc4, 0x56, 0x18, 0x57, 0x63, 0xe0, 0x36,
+  0xdd, 0x2d, 0xb1, 0xcc, 0xff, 0xff, 0xfd, 0x98,
+  0x0a, 0xe6, 0x7f, 0x4e, 0xf1, 0xfa, 0xe5, 0x9d,
+  0x5f, 0xe5, 0x0c, 0xc6, 0x1d, 0x3a, 0xab, 0x41,
+  0xd3, 0xb7, 0x32, 0xc7, 0x43, 0xd1, 0x89, 0x58,
+  0x45, 0x5c, 0x72, 0x7a, 0x90, 0x6a, 0x87, 0x4f,
+  0xad, 0xf5, 0xc1, 0x32, 0x7f, 0xde, 0x17, 0xe0,
+  0xd1, 0xaf, 0x6c, 0x68, 0x83, 0x5c, 0x69, 0x67,
+  0xdc, 0x9e, 0x62, 0x9d, 0x3f, 0x3e, 0xdf, 0xea,
+  0x6e, 0x74, 0xb1, 0x0f, 0x4f, 0xe4, 0xb3, 0xff,
+  0xfe, 0xe0, 0xdf, 0x2d, 0x75, 0xcf, 0xd3, 0x7c,
+  0x1f, 0x51, 0xcc, 0x3a, 0x1e, 0x9a, 0x06, 0x42,
+  0xbf, 0xe4, 0xd3, 0xf0, 0xe6, 0xd5, 0xb2, 0x9d,
+  0x3f, 0xff, 0xb5, 0xff, 0x69, 0xd1, 0xbf, 0xfd,
+  0x7a, 0xfa, 0x9b, 0x78, 0x27, 0x4f, 0xff, 0xf5,
+  0x6a, 0xa3, 0x75, 0x73, 0x32, 0xf5, 0xdf, 0x5e,
+  0x7e, 0x1d, 0x3d, 0x6c, 0xf3, 0x63, 0xa3, 0xc8,
+  0x89, 0xb3, 0x34, 0xcc, 0xdd, 0x0d, 0x17, 0xe4,
+  0xff, 0xcf, 0xbe, 0xaf, 0x7b, 0x2f, 0x75, 0x61,
+  0xd3, 0xff, 0x7b, 0x3f, 0x99, 0x5d, 0x0f, 0xab,
+  0x0e, 0x8a, 0x51, 0x17, 0x54, 0x69, 0xef, 0xfd,
+  0x50, 0xe8, 0x54, 0xc6, 0xb6, 0x23, 0xc8, 0x59,
+  0xf1, 0x24, 0xff, 0xff, 0xcd, 0xeb, 0x6f, 0x31,
+  0xcd, 0x3f, 0x87, 0x7d, 0xbd, 0x4d, 0x53, 0xd4,
+  0x1d, 0x3f, 0xee, 0x7b, 0x39, 0xf7, 0xaa, 0xe9,
+  0x3a, 0x7b, 0x2b, 0xef, 0x9d, 0x1f, 0x3e, 0x0d,
+  0x4f, 0xe7, 0xb7, 0xeb, 0xd5, 0x3a, 0x7f, 0xd7,
+  0xa8, 0x3d, 0x4d, 0x2f, 0xcb, 0x9d, 0x0a, 0x7c,
+  0xb8, 0x49, 0x33, 0x5a, 0x9d, 0x26, 0x1d, 0x14,
+  0x9a, 0x86, 0xec, 0x62, 0x7f, 0xff, 0xd6, 0xf5,
+  0x37, 0xca, 0x6e, 0x22, 0xb7, 0x06, 0xff, 0xbe,
+  0xd8, 0x74, 0xe0, 0x84, 0x25, 0x4f, 0x6d, 0xb7,
+  0x7c, 0xa7, 0x17, 0x93, 0xfe, 0xeb, 0x27, 0xbb,
+  0x45, 0x7a, 0xc7, 0x42, 0xa6, 0x44, 0x84, 0xfe,
+  0x84, 0x5d, 0x8c, 0xa7, 0xfe, 0xcf, 0xd3, 0x7c,
+  0x1f, 0x51, 0xcc, 0x3a, 0x7d, 0x97, 0x7b, 0x2c,
+  0x74, 0x29, 0xf5, 0xd5, 0x12, 0x60, 0x58, 0xe9,
+  0xfa, 0x86, 0x9e, 0xdc, 0x1a, 0x0e, 0x9f, 0xda,
+  0x6d, 0x97, 0xb7, 0xae, 0x74, 0xde, 0x13, 0xa3,
+  0x75, 0x1f, 0xf7, 0x8d, 0x2c, 0x6b, 0x3f, 0xf6,
+  0xcb, 0xb0, 0xad, 0xfc, 0x9e, 0xd8, 0xe9, 0xfa,
+  0xda, 0xd0, 0xd5, 0xbc, 0x74, 0x6c, 0x7e, 0xd6,
+  0x45, 0x93, 0x9b, 0xa3, 0x37, 0x77, 0x75, 0x87,
+  0x14, 0x6e, 0x82, 0xbd, 0xa1, 0xb1, 0x92, 0x84,
+  0xe9, 0x8c, 0xa7, 0xc6, 0xad, 0x47, 0x10, 0x26,
+  0xac, 0x2c, 0xb4, 0xa0, 0xde, 0x41, 0x04, 0x36,
+  0xbf, 0x08, 0x8a, 0xc6, 0xd5, 0x78, 0x56, 0x04,
+  0x87, 0x72, 0x12, 0x9b, 0xe1, 0x57, 0x0e, 0x67,
+  0xc8, 0x5a, 0x9c, 0x53, 0x3f, 0xf9, 0xcc, 0xe7,
+  0xbb, 0x05, 0x3b, 0x90, 0xd1, 0x36, 0x4f, 0xe7,
+  0x60, 0xa7, 0x72, 0x1a, 0x2a, 0xd9, 0xfc, 0xf7,
+  0xeb, 0x7f, 0xab, 0xce, 0x9e, 0xcb, 0x75, 0xce,
+  0x96, 0xe9, 0x87, 0xa9, 0xf3, 0x49, 0xf0, 0xa7,
+  0x72, 0x1a, 0x2b, 0x49, 0xff, 0xe4, 0x51, 0xc0,
+  0x73, 0x39, 0xeb, 0xe4, 0x3a, 0x7f, 0xf9, 0xf5,
+  0xcf, 0xab, 0x3b, 0x2f, 0x75, 0x61, 0xd3, 0x5e,
+  0xea, 0x89, 0x7e, 0x4a, 0x9f, 0xca, 0xdb, 0x7d,
+  0xfe, 0xa0, 0x3a, 0x7e, 0xa3, 0x2d, 0xec, 0x61,
+  0xd3, 0xfd, 0x8d, 0xff, 0x50, 0xd2, 0xfa, 0x9d,
+  0x3f, 0x9f, 0x97, 0xef, 0x83, 0x53, 0xa4, 0xe6,
+  0xe2, 0x7e, 0x58, 0x59, 0xe8, 0x63, 0xd8, 0xb7,
+  0x8d, 0xbe, 0x5b, 0x73, 0xc9, 0xfc, 0xec, 0x14,
+  0xee, 0x43, 0x45, 0x81, 0x3e, 0x14, 0xee, 0x43,
+  0x44, 0xeb, 0x3f, 0xff, 0xac, 0xb4, 0x6d, 0x8c,
+  0x75, 0x6b, 0x96, 0xf5, 0x75, 0xa0, 0xe9, 0xf3,
+  0x99, 0xcf, 0x76, 0x22, 0x55, 0xa3, 0x09, 0xf0,
+  0xa7, 0x72, 0x1a, 0x2d, 0x99, 0xff, 0x01, 0x6a,
+  0xeb, 0x79, 0x38, 0x4e, 0x93, 0xb0, 0xfb, 0x38,
+  0xc2, 0x79, 0x3b, 0x90, 0xd1, 0x73, 0x49, 0x87,
+  0x4c, 0xec, 0x13, 0x76, 0x12, 0xb9, 0xfc, 0xec,
+  0x14, 0xee, 0x43, 0x45, 0xdf, 0x3c, 0xed, 0x3b,
+  0x00, 0xe8, 0x56, 0xd6, 0x5b, 0x29, 0xf7, 0x28,
+  0x61, 0x4a, 0x97, 0xa5, 0x40, 0x8b, 0x93, 0x21,
+  0xa0, 0x08, 0x56, 0x55, 0x86, 0xe5, 0x7b, 0xce,
+  0xe7, 0xfd, 0xfe, 0x72, 0xd6, 0xac, 0xe7, 0x9d,
+  0x3f, 0xbf, 0x46, 0x37, 0xdd, 0x74, 0x9d, 0x3e,
+  0x14, 0xee, 0x43, 0x44, 0xaf, 0x3f, 0xef, 0xf0,
+  0x76, 0xb2, 0xd1, 0x81, 0x3a, 0x7b, 0x5e, 0x17,
+  0x9d, 0x3f, 0xff, 0xbd, 0x7e, 0x67, 0x7c, 0x16,
+  0x0f, 0x7e, 0x84, 0xf5, 0x07, 0x46, 0xc8, 0x83,
+  0xe2, 0x18, 0xd9, 0x1c, 0xb6, 0x86, 0x14, 0xee,
+  0x7b, 0x95, 0x37, 0x6c, 0x38, 0xac, 0x62, 0xb3,
+  0xae, 0xbb, 0x15, 0x3f, 0xfa, 0xdd, 0xeb, 0xab,
+  0xfc, 0x34, 0x6a, 0x02, 0xa7, 0xf7, 0x23, 0xb6,
+  0x16, 0xed, 0xca, 0x7c, 0xf5, 0x1c, 0x93, 0x91,
+  0x55, 0x73, 0x23, 0xb3, 0x6d, 0x0a, 0xd9, 0xff,
+  0xce, 0x67, 0x3d, 0xd8, 0x29, 0xdc, 0x86, 0x89,
+  0x86, 0x7f, 0xfe, 0xc7, 0x6f, 0x1e, 0x03, 0xb4,
+  0xdd, 0xe1, 0x5a, 0xbc, 0xe9, 0xff, 0xb7, 0x4c,
+  0xa5, 0xfa, 0xf5, 0xfe, 0xaf, 0x3a, 0x7f, 0x2f,
+  0x51, 0x7d, 0x3c, 0x27, 0x4f, 0xb8, 0x5f, 0xcc,
+  0x3a, 0x3e, 0x7b, 0x1a, 0x99, 0xcf, 0xcc, 0x5c,
+  0xfd, 0xf7, 0x0e, 0x9f, 0x2e, 0x7e, 0xfb, 0x87,
+  0x4f, 0xd6, 0xf5, 0xeb, 0xd4, 0xe8, 0x3d, 0x86,
+  0x17, 0xcf, 0xff, 0xfb, 0xf8, 0x16, 0xfb, 0xe5,
+  0xb4, 0x7f, 0x28, 0xf6, 0x7e, 0x97, 0xd4, 0xe9,
+  0xf9, 0xb6, 0xfb, 0xfd, 0x40, 0x74, 0xff, 0xe5,
+  0xb8, 0x15, 0xf9, 0x4d, 0xe8, 0xd4, 0x27, 0x42,
+  0x9f, 0xef, 0x8c, 0x67, 0xea, 0xfb, 0x4b, 0x3a,
+  0xe7, 0x4f, 0xff, 0xf8, 0x71, 0xb2, 0xfe, 0xfa,
+  0x37, 0xfd, 0x6d, 0xde, 0xba, 0xde, 0xa7, 0x4b,
+  0x29, 0x44, 0xf8, 0x97, 0xcf, 0x7d, 0x41, 0xbc,
+  0xe9, 0xee, 0xdf, 0xb6, 0x1d, 0x27, 0x37, 0x15,
+  0xc1, 0xed, 0x0a, 0x24, 0x7b, 0x69, 0x22, 0xd0,
+  0xf0, 0xfc, 0x30, 0x2e, 0x51, 0xa9, 0x1c, 0xf8,
+  0x53, 0xb9, 0x0d, 0x15, 0x74, 0xff, 0x3d, 0xd8,
+  0x29, 0xdc, 0x86, 0x88, 0xf2, 0x4e, 0xc3, 0xf1,
+  0xe3, 0x09, 0xfc, 0xec, 0x14, 0xee, 0x43, 0x45,
+  0x83, 0x3f, 0x9d, 0x82, 0x9d, 0xc8, 0x68, 0xb2,
+  0xa7, 0xf3, 0xb0, 0x53, 0xb9, 0x0d, 0x16, 0x9c,
+  0xf2, 0x77, 0x21, 0xa2, 0xdc, 0x9f, 0xf9, 0x70,
+  0x73, 0xfa, 0x2d, 0x94, 0x84, 0xe8, 0x13, 0xef,
+  0xa9, 0x5c, 0xff, 0x2f, 0xf5, 0x62, 0xd6, 0xfe,
+  0x3a, 0x7f, 0xdc, 0xf7, 0x60, 0xa7, 0x72, 0x1a,
+  0x28, 0x79, 0xfa, 0xbd, 0x4d, 0x6f, 0xe3, 0xa7,
+  0xef, 0xb7, 0x30, 0x56, 0xa7, 0x4f, 0xff, 0xd9,
+  0xb5, 0x97, 0x7b, 0xaf, 0xfe, 0x05, 0x6a, 0xa0,
+  0x2a, 0x4e, 0xc4, 0xd6, 0xbc, 0x42, 0xc3, 0x9b,
+  0xa3, 0x6a, 0x5d, 0xb8, 0x5f, 0x3f, 0x9d, 0x82,
+  0x9d, 0xc8, 0x68, 0xbc, 0xe1, 0x59, 0x16, 0x4f,
+  0x44, 0xd9, 0x4b, 0x25, 0xf0, 0xd3, 0x0f, 0xf1,
+  0x26, 0x61, 0xdd, 0x8e, 0xff, 0x28, 0x11, 0xb3,
+  0x0c, 0xfe, 0x76, 0x0a, 0x77, 0x21, 0xa2, 0x96,
+  0x9f, 0xce, 0xc1, 0x4e, 0xe4, 0x34, 0x58, 0x53,
+  0xf9, 0xd8, 0x29, 0xdc, 0x86, 0x8b, 0x2e, 0x79,
+  0xda, 0x77, 0x5f, 0x37, 0x53, 0xa7, 0x3b, 0x7b,
+  0x0e, 0x9e, 0x47, 0x2d, 0x50, 0xf4, 0xb5, 0x34,
+  0x9f, 0xfc, 0xe6, 0x73, 0xdd, 0x82, 0x9d, 0xc8,
+  0x68, 0xa3, 0x27, 0xf3, 0x95, 0xb2, 0x8a, 0x80,
+  0xe8, 0x7a, 0x77, 0xe2, 0x76, 0xc3, 0xbe, 0x84,
+  0x6d, 0x4e, 0x2e, 0xa5, 0x3f, 0xf3, 0xb9, 0xee,
+  0xc1, 0x4e, 0xe4, 0x34, 0x47, 0x33, 0xff, 0x9c,
+  0xce, 0x7b, 0xb0, 0x53, 0xb9, 0x0d, 0x13, 0x94,
+  0xfe, 0x76, 0x0a, 0x77, 0x21, 0xa2, 0xcc, 0x9f,
+  0xf9, 0xca, 0x01, 0x5b, 0xdb, 0xa9, 0x79, 0xd3,
+  0xf9, 0xd8, 0x29, 0xdc, 0x86, 0x8b, 0x76, 0x7f,
+  0xf3, 0x99, 0xcf, 0x76, 0x0a, 0x77, 0x21, 0xa2,
+  0x90, 0x9f, 0xf9, 0xdc, 0xf7, 0x60, 0xa7, 0x72,
+  0x1a, 0x25, 0x28, 0xa1, 0x3f, 0x56, 0x93, 0x18,
+  0xa4, 0x03, 0xbf, 0xa1, 0xdc, 0xed, 0xbd, 0x4a,
+  0x7f, 0xdc, 0xf7, 0x60, 0xa7, 0x72, 0x1a, 0x27,
+  0x69, 0xff, 0xf7, 0xb6, 0xd5, 0x8a, 0xdf, 0xdb,
+  0x7d, 0x7f, 0x88, 0x74, 0x9c, 0xc4, 0x4f, 0xf2,
+  0x34, 0xff, 0xdc, 0xcb, 0x62, 0x75, 0x97, 0x7b,
+  0xce, 0x9f, 0xfb, 0xf9, 0x6e, 0xa3, 0x2b, 0xfe,
+  0xa4, 0xe9, 0xb7, 0x1d, 0xb2, 0x21, 0xea, 0x87,
+  0x0c, 0x47, 0x16, 0xe4, 0x2b, 0xe7, 0xc2, 0x9d,
+  0xc8, 0x68, 0x8b, 0x27, 0xfd, 0xcf, 0x76, 0x0a,
+  0x77, 0x21, 0xa2, 0x5d, 0x9f, 0xff, 0xb3, 0x6b,
+  0x2e, 0xf7, 0x5f, 0xfc, 0x0a, 0xd5, 0x40, 0x54,
+  0x9d, 0x88, 0xd3, 0x61, 0x86, 0xe2, 0x34, 0xff,
+  0xe7, 0x33, 0x9e, 0xec, 0x14, 0xee, 0x43, 0x44,
+  0xc5, 0x3f, 0x60, 0xa7, 0x72, 0x1a, 0x2a, 0x99,
+  0xff, 0xff, 0xc3, 0xd6, 0xa5, 0xf9, 0x77, 0x5b,
+  0xaa, 0x3e, 0x0d, 0xed, 0xe1, 0x79, 0xd0, 0xe4,
+  0x56, 0x71, 0xac, 0xff, 0xe7, 0x33, 0x9e, 0xec,
+  0x14, 0xee, 0x43, 0x44, 0xe9, 0x3f, 0xbd, 0xc2,
+  0xaf, 0xe6, 0xc7, 0x4f, 0x9a, 0x56, 0x96, 0xa7,
+  0x4f, 0xc1, 0xcf, 0x36, 0xcf, 0x9d, 0x3d, 0xeb,
+  0x2b, 0xbc, 0x7a, 0xd5, 0x28, 0x9f, 0xfb, 0x5a,
+  0xdd, 0x69, 0x76, 0xad, 0x79, 0x87, 0x43, 0x11,
+  0x05, 0x63, 0x99, 0xff, 0x73, 0xdd, 0x82, 0x9d,
+  0xc8, 0x68, 0x9d, 0xe7, 0xd7, 0xd7, 0x99, 0xe2,
+  0xa4, 0xed, 0x93, 0x9b, 0xc8, 0xc2, 0x98, 0x47,
+  0xc8, 0xd3, 0xff, 0x9c, 0xce, 0x7b, 0xb0, 0x53,
+  0xb9, 0x0d, 0x14, 0x2c, 0xff, 0xe7, 0x33, 0x9e,
+  0xec, 0x14, 0xee, 0x43, 0x45, 0x25, 0x3f, 0xff,
+  0xb2, 0xae, 0xdf, 0x8d, 0x5b, 0x99, 0x7b, 0x2d,
+  0xf5, 0x61, 0xd1, 0x42, 0xe4, 0xb3, 0xce, 0x12,
+  0x1f, 0xc2, 0x44, 0xc8, 0xfb, 0x40, 0x93, 0xaa,
+  0x96, 0xe2, 0x94, 0xfe, 0x76, 0x0a, 0x77, 0x21,
+  0xa2, 0x24, 0x9f, 0xfc, 0xe6, 0x73, 0xdd, 0x82,
+  0x9d, 0xc8, 0x68, 0x97, 0xa7, 0xc2, 0x9d, 0xc8,
+  0x68, 0xa5, 0xe7, 0xff, 0x63, 0xd4, 0x15, 0x15,
+  0xa5, 0xfe, 0x61, 0xd3, 0xe6, 0xff, 0x31, 0x6a,
+  0x74, 0xfb, 0x9b, 0x60, 0xd4, 0xe9, 0x2e, 0xc7,
+  0xa2, 0xc2, 0xa9, 0x3b, 0x11, 0xe4, 0xd1, 0x85,
+  0xe1, 0x35, 0x3f, 0x9d, 0x82, 0x9d, 0xc8, 0x68,
+  0xa7, 0x27, 0xfd, 0xe1, 0xea, 0xdb, 0x33, 0xe8,
+  0x74, 0xff, 0xb2, 0xca, 0x38, 0xe0, 0x84, 0x25,
+  0x4d, 0xe0, 0x9d, 0x35, 0x0e, 0xd9, 0x11, 0xbb,
+  0x87, 0x6d, 0xe7, 0x93, 0xe1, 0x4e, 0xe4, 0x34,
+  0x57, 0x93, 0xff, 0xf6, 0x6d, 0x65, 0xde, 0xeb,
+  0xff, 0x81, 0x5a, 0xa8, 0x0a, 0x93, 0xb1, 0x11,
+  0xbb, 0x86, 0x13, 0xff, 0x3b, 0x9e, 0xec, 0x14,
+  0xee, 0x43, 0x44, 0x8f, 0x3b, 0xc0, 0x53, 0xa7,
+  0x26, 0x30, 0xa7, 0x17, 0x73, 0xe1, 0x4e, 0xe4,
+  0x34, 0x49, 0x13, 0xce, 0xe7, 0xb9, 0x4f, 0x67,
+  0x0a, 0x67, 0xfe, 0x77, 0x3d, 0xd8, 0x29, 0xdc,
+  0x86, 0x89, 0x2a, 0x7c, 0x29, 0xdc, 0x86, 0x8b,
+  0xc6, 0x7e, 0xd7, 0xf4, 0xf5, 0x35, 0x3a, 0x7d,
+  0x5a, 0xdf, 0x10, 0xe9, 0xfe, 0x7b, 0xb0, 0x53,
+  0xb9, 0x0d, 0x12, 0x6c, 0x9d, 0x88, 0xc7, 0xa4,
+  0xc0, 0x4c, 0x38, 0x9a, 0x15, 0x77, 0x26, 0x83,
+  0xb7, 0xc6, 0x89, 0xb1, 0xdf, 0xa1, 0x90, 0xd4,
+  0x34, 0x58, 0x57, 0x68, 0x60, 0x5c, 0xdf, 0x58,
+  0xc4, 0xe1, 0x63, 0x76, 0xd5, 0xa2, 0x3a, 0xe7,
+  0xc7, 0x93, 0xb4, 0xa1, 0xac, 0xb7, 0x5a, 0xda,
+  0x65, 0x2c, 0x25, 0x7f, 0xbd, 0x4c, 0xf3, 0xdf,
+  0xa7, 0x3d, 0x37, 0x71, 0xd8, 0x35, 0x4e, 0xc3,
+  0x1a, 0x47, 0xab, 0x31, 0x1a, 0x11, 0x69, 0xda,
+  0x8e, 0xa7, 0xb9, 0x02, 0x58, 0x73, 0x77, 0x0b,
+  0x1f, 0xcf, 0x63, 0x56, 0x92, 0xbb, 0x7a, 0xe8,
+  0x7f, 0x5a, 0x60, 0xb3, 0x69, 0x4c, 0x41, 0x94,
+  0xa1, 0xb9, 0x1f, 0x5e, 0xf9, 0xd9, 0x46, 0xf9,
+  0xe4, 0xb8,
 };
 
-static const unsigned kPreloadedHSTSBits = 97858;
+static const unsigned kPreloadedHSTSBits = 97871;
 
-static const unsigned kHSTSRootPosition = 97280;
+static const unsigned kHSTSRootPosition = 97293;
 
 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_STATIC_H_
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index 39ca582..59eb9f7 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -186,6 +186,14 @@
         "DigiCertEVRoot",
         "FacebookBackup"
       ]
+    },
+    {
+      "name": "spideroak",
+      "static_spki_hashes": [
+        "RapidSSL",
+        "SpiderOak1",
+        "SpiderOak2"
+      ]
     }
   ],
 
@@ -1266,7 +1274,7 @@
     { "name": "ravchat.com", "include_subdomains": true, "mode": "force-https" },
     { "name": "sciencex.com", "include_subdomains": true, "mode": "force-https" },
     { "name": "shiinko.com", "include_subdomains": true, "mode": "force-https" },
-    { "name": "spideroak.com", "include_subdomains": true, "mode": "force-https" },
+    { "name": "spideroak.com", "include_subdomains": true, "mode": "force-https", "pins": "spideroak" },
     { "name": "thorncreek.net", "include_subdomains": true, "mode": "force-https" },
     { "name": "tno.io", "include_subdomains": true, "mode": "force-https" },
     { "name": "translatoruk.co.uk", "include_subdomains": true, "mode": "force-https" },
@@ -1393,9 +1401,10 @@
     { "name": "fleximus.org", "include_subdomains": true, "mode": "force-https" },
 
     // Facebook would like to have pinning enforced on (*.)facebook.com and
-    // HSTS enforced on specific names. We can't (yet) represent that in JSON
-    // So we're currently only applying pinning on the specific names.
-    { "name": "facebook.com", "mode": "force-https", "pins": "facebook", "include_subdomains_for_pinning": true },
+    // HSTS enforced on specific names. We have the
+    // "include_subdomains_for_pinning" flag that can do that, but it triggered a
+    // wave of pinning failures and so isn't used until that can be investigated.
+    { "name": "facebook.com", "mode": "force-https", "pins": "facebook" },
     { "name": "www.facebook.com", "include_subdomains": true, "mode": "force-https", "pins": "facebook" },
     { "name": "m.facebook.com", "include_subdomains": true, "mode": "force-https", "pins": "facebook" },
     { "name": "tablet.facebook.com", "include_subdomains": true, "mode": "force-https", "pins": "facebook" },
@@ -1777,6 +1786,7 @@
     "DROPBOX_COM",
     "YOUTUBE_NOCOOKIE_COM",
     "2MDN_NET",
-    "FACEBOOK_COM"
+    "FACEBOOK_COM",
+    "SPIDEROAK_COM"
   ]
 }
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index cf5f243..1872e72 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -540,9 +540,7 @@
   EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
   EXPECT_TRUE(StaticShouldRedirect("facebook.com"));
 
-  EXPECT_TRUE(state.GetStaticDomainState("foo.facebook.com", &domain_state));
-  EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
-  EXPECT_FALSE(StaticShouldRedirect("foo.facebook.com"));
+  EXPECT_FALSE(state.GetStaticDomainState("foo.facebook.com", &domain_state));
 
   EXPECT_TRUE(state.GetStaticDomainState("www.facebook.com", &domain_state));
   EXPECT_FALSE(domain_state.pkp.spki_hashes.empty());
diff --git a/net/net.gyp b/net/net.gyp
index e9379e0..3c9a520 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -487,10 +487,14 @@
             ['include', '^base/platform_mime_util_linux\\.cc$'],
             ['include', '^base/address_tracker_linux\\.cc$'],
             ['include', '^base/address_tracker_linux\\.h$'],
+            ['include', '^base/net_util_linux\\.cc$'],
+            ['include', '^base/net_util_linux\\.h$'],
           ],
         }],
         ['OS == "ios"', {
           'sources/': [
+            ['include', '^base/net_util_mac\\.cc$'],
+            ['include', '^base/net_util_mac\\.h$'],
             ['include', '^base/network_change_notifier_mac\\.cc$'],
             ['include', '^base/network_config_watcher_mac\\.cc$'],
             ['include', '^base/platform_mime_util_mac\\.mm$'],
diff --git a/net/net.gypi b/net/net.gypi
index fef6136..337f016 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -246,7 +246,11 @@
       'base/net_log_logger.h',
       'base/net_log_util.cc',
       'base/net_log_util.h',
+      'base/net_util_linux.cc',
+      'base/net_util_mac.cc',
       'base/net_util_win.cc',
+      'base/network_activity_monitor.cc',
+      'base/network_activity_monitor.h',
       'base/network_change_notifier.cc',
       'base/network_change_notifier.h',
       'base/network_change_notifier_factory.h',
@@ -275,8 +279,12 @@
       'base/request_priority.h',
       'base/sdch_manager.cc',
       'base/sdch_manager.h',
+      'base/sdch_net_log_params.cc',
+      'base/sdch_net_log_params.h',
       'base/sdch_observer.cc',
       'base/sdch_observer.h',
+      'base/sdch_problem_code_list.h',
+      'base/sdch_problem_codes.h',
       'base/static_cookie_policy.cc',
       'base/static_cookie_policy.h',
       'base/test_data_stream.cc',
@@ -751,8 +759,6 @@
       'quic/congestion_control/cubic.h',
       'quic/congestion_control/hybrid_slow_start.cc',
       'quic/congestion_control/hybrid_slow_start.h',
-      'quic/congestion_control/leaky_bucket.cc',
-      'quic/congestion_control/leaky_bucket.h',
       'quic/congestion_control/loss_detection_interface.cc',
       'quic/congestion_control/loss_detection_interface.h',
       'quic/congestion_control/pacing_sender.cc',
@@ -785,6 +791,8 @@
       'quic/crypto/aes_128_gcm_12_encrypter.h',
       'quic/crypto/aes_128_gcm_12_encrypter_nss.cc',
       'quic/crypto/aes_128_gcm_12_encrypter_openssl.cc',
+      'quic/crypto/cached_network_parameters.cc',
+      'quic/crypto/cached_network_parameters.h',
       'quic/crypto/cert_compressor.cc',
       'quic/crypto/cert_compressor.h',
       'quic/crypto/chacha20_poly1305_decrypter.h',
@@ -1276,6 +1284,7 @@
       'base/net_log_util_unittest.cc',
       'base/net_util_unittest.cc',
       'base/net_util_icu_unittest.cc',
+      'base/network_activity_monitor_unittest.cc',
       'base/network_change_notifier_unittest.cc',
       'base/network_change_notifier_win_unittest.cc',
       'base/prioritized_dispatcher_unittest.cc',
@@ -1440,7 +1449,6 @@
       'quic/congestion_control/cube_root_test.cc',
       'quic/congestion_control/cubic_test.cc',
       'quic/congestion_control/hybrid_slow_start_test.cc',
-      'quic/congestion_control/leaky_bucket_test.cc',
       'quic/congestion_control/pacing_sender_test.cc',
       'quic/congestion_control/prr_sender_test.cc',
       'quic/congestion_control/rtt_stats_test.cc',
diff --git a/net/quic/congestion_control/hybrid_slow_start.cc b/net/quic/congestion_control/hybrid_slow_start.cc
index 4b1e842..e3789b4 100644
--- a/net/quic/congestion_control/hybrid_slow_start.cc
+++ b/net/quic/congestion_control/hybrid_slow_start.cc
@@ -23,6 +23,7 @@
 
 HybridSlowStart::HybridSlowStart(const QuicClock* clock)
     : clock_(clock),
+      ack_train_detection_(true),
       started_(false),
       hystart_found_(NOT_FOUND),
       last_sent_sequence_number_(0),
@@ -84,12 +85,8 @@
   // more than the capacity.
   // This first trigger will not come into play until we hit roughly 9.6 Mbps
   // with delayed acks (or 4.8Mbps without delayed acks)
-  // TODO(ianswett): QUIC always uses delayed acks, even at the beginning, so
-  // this should likely be at least 4ms.
-  // TODO(pwestin): we need to make sure our pacing don't trigger this detector.
-  // TODO(ianswett): Pacing or other cases could be handled by checking the send
-  // time of the first acked packet in a receive round.
-  if (current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <=
+  if (ack_train_detection_ &&
+      current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <=
           kHybridStartDelayMinThresholdUs) {
     last_close_ack_pair_time_ = current_time;
     if (current_time.Subtract(round_start_).ToMicroseconds() >=
diff --git a/net/quic/congestion_control/hybrid_slow_start.h b/net/quic/congestion_control/hybrid_slow_start.h
index 5d36c53..cee9a60 100644
--- a/net/quic/congestion_control/hybrid_slow_start.h
+++ b/net/quic/congestion_control/hybrid_slow_start.h
@@ -53,6 +53,14 @@
   // Call for the start of each receive round (burst) in the slow start phase.
   void StartReceiveRound(QuicPacketSequenceNumber last_sent);
 
+  void set_ack_train_detection(bool ack_train_detection) {
+    ack_train_detection_ = ack_train_detection;
+  }
+
+  bool ack_train_detection() const {
+    return ack_train_detection_;
+  }
+
   // Whether slow start has started.
   bool started() const {
     return started_;
@@ -67,6 +75,7 @@
   };
 
   const QuicClock* clock_;
+  bool ack_train_detection_;
   // Whether the hybrid slow start has been started.
   bool started_;
   HystartState hystart_found_;
diff --git a/net/quic/congestion_control/hybrid_slow_start_test.cc b/net/quic/congestion_control/hybrid_slow_start_test.cc
index dd74933..bcdf8d9 100644
--- a/net/quic/congestion_control/hybrid_slow_start_test.cc
+++ b/net/quic/congestion_control/hybrid_slow_start_test.cc
@@ -54,26 +54,33 @@
   // At a typical RTT 60 ms, assuming that the inter arrival timestamp is 1 ms,
   // we expect to be able to send a burst of 30 packet before we trigger the
   // ack train detection.
-  const int kMaxLoopCount = 5;
-  QuicPacketSequenceNumber sequence_number = 2;
-  QuicPacketSequenceNumber end_sequence_number = 2;
-  for (int burst = 0; burst < kMaxLoopCount; ++burst) {
+  // Run this test for both enabled and disabled ack train detection.
+  for (int i = 0; i < 2; ++i) {
+    const bool ack_train_detection = (i == 1);
+    slow_start_->set_ack_train_detection(ack_train_detection);
+
+    const int kMaxLoopCount = 5;
+    QuicPacketSequenceNumber sequence_number = 2;
+    QuicPacketSequenceNumber end_sequence_number = 2;
+    for (int burst = 0; burst < kMaxLoopCount; ++burst) {
+      slow_start_->StartReceiveRound(end_sequence_number);
+      do {
+        clock_.AdvanceTime(one_ms_);
+        EXPECT_FALSE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100));
+      } while (!slow_start_->IsEndOfRound(sequence_number++));
+      end_sequence_number *= 2;  // Exponential growth.
+    }
     slow_start_->StartReceiveRound(end_sequence_number);
-    do {
+
+    for (int n = 0;
+         n < 29 && !slow_start_->IsEndOfRound(sequence_number++); ++n) {
       clock_.AdvanceTime(one_ms_);
       EXPECT_FALSE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100));
-    }  while (!slow_start_->IsEndOfRound(sequence_number++));
-    end_sequence_number *= 2;  // Exponential growth.
-  }
-  slow_start_->StartReceiveRound(end_sequence_number);
-
-  for (int n = 0;
-       n < 29 && !slow_start_->IsEndOfRound(sequence_number++); ++n) {
+    }
     clock_.AdvanceTime(one_ms_);
-    EXPECT_FALSE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100));
+    EXPECT_EQ(ack_train_detection,
+              slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100));
   }
-  clock_.AdvanceTime(one_ms_);
-  EXPECT_TRUE(slow_start_->ShouldExitSlowStart(rtt_, rtt_, 100));
 }
 
 TEST_F(HybridSlowStartTest, Delay) {
diff --git a/net/quic/congestion_control/leaky_bucket.cc b/net/quic/congestion_control/leaky_bucket.cc
deleted file mode 100644
index f3972f6..0000000
--- a/net/quic/congestion_control/leaky_bucket.cc
+++ /dev/null
@@ -1,54 +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/quic/congestion_control/leaky_bucket.h"
-
-#include "base/time/time.h"
-
-namespace net {
-
-LeakyBucket::LeakyBucket(QuicBandwidth draining_rate)
-    : bytes_(0),
-      time_last_updated_(QuicTime::Zero()),
-      draining_rate_(draining_rate) {
-}
-
-void LeakyBucket::SetDrainingRate(QuicTime now, QuicBandwidth draining_rate) {
-  Update(now);
-  draining_rate_ = draining_rate;
-}
-
-void LeakyBucket::Add(QuicTime now, QuicByteCount bytes) {
-  Update(now);
-  bytes_ += bytes;
-}
-
-QuicTime::Delta LeakyBucket::TimeRemaining(QuicTime now) const {
-  QuicTime::Delta time_since_last_update = now.Subtract(time_last_updated_);
-  QuicTime::Delta send_delay = QuicTime::Delta::FromMicroseconds(
-      (bytes_ * base::Time::kMicrosecondsPerSecond) /
-      draining_rate_.ToBytesPerSecond());
-  if (send_delay < time_since_last_update) {
-    return QuicTime::Delta::Zero();
-  }
-  return send_delay.Subtract(time_since_last_update);
-}
-
-QuicByteCount LeakyBucket::BytesPending(QuicTime now) {
-  Update(now);
-  return bytes_;
-}
-
-void LeakyBucket::Update(QuicTime now) {
-  QuicTime::Delta elapsed_time = now.Subtract(time_last_updated_);
-  QuicByteCount bytes_cleared = draining_rate_.ToBytesPerPeriod(elapsed_time);
-  if (bytes_cleared >= bytes_) {
-    bytes_ = 0;
-  } else {
-    bytes_ -= bytes_cleared;
-  }
-  time_last_updated_ = now;
-}
-
-}  // namespace net
diff --git a/net/quic/congestion_control/leaky_bucket.h b/net/quic/congestion_control/leaky_bucket.h
deleted file mode 100644
index eb4cdb0..0000000
--- a/net/quic/congestion_control/leaky_bucket.h
+++ /dev/null
@@ -1,49 +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.
-//
-// Helper class to track the rate data can leave the buffer for pacing.
-// A leaky bucket drains the data at a constant rate regardless of fullness of
-// the buffer.
-// See http://en.wikipedia.org/wiki/Leaky_bucket for more details.
-
-#ifndef NET_QUIC_CONGESTION_CONTROL_LEAKY_BUCKET_H_
-#define NET_QUIC_CONGESTION_CONTROL_LEAKY_BUCKET_H_
-
-#include "base/basictypes.h"
-#include "net/base/net_export.h"
-#include "net/quic/quic_bandwidth.h"
-#include "net/quic/quic_protocol.h"
-#include "net/quic/quic_time.h"
-
-namespace net {
-
-class NET_EXPORT_PRIVATE LeakyBucket {
- public:
-  explicit LeakyBucket(QuicBandwidth draining_rate);
-
-  // Set the rate at which the bytes leave the buffer.
-  void SetDrainingRate(QuicTime now, QuicBandwidth draining_rate);
-
-  // Add data to the buffer.
-  void Add(QuicTime now, QuicByteCount bytes);
-
-  // Time until the buffer is empty.
-  QuicTime::Delta TimeRemaining(QuicTime now) const;
-
-  // Number of bytes in the buffer.
-  QuicByteCount BytesPending(QuicTime now);
-
- private:
-  void Update(QuicTime now);
-
-  QuicByteCount bytes_;
-  QuicTime time_last_updated_;
-  QuicBandwidth draining_rate_;
-
-  DISALLOW_COPY_AND_ASSIGN(LeakyBucket);
-};
-
-}  // namespace net
-
-#endif  // NET_QUIC_CONGESTION_CONTROL_LEAKY_BUCKET_H_
diff --git a/net/quic/congestion_control/leaky_bucket_test.cc b/net/quic/congestion_control/leaky_bucket_test.cc
deleted file mode 100644
index 8387ada..0000000
--- a/net/quic/congestion_control/leaky_bucket_test.cc
+++ /dev/null
@@ -1,75 +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 "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "net/quic/congestion_control/leaky_bucket.h"
-#include "net/quic/test_tools/mock_clock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace test {
-
-class LeakyBucketTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    leaky_bucket_.reset(new LeakyBucket(QuicBandwidth::Zero()));
-  }
-  MockClock clock_;
-  scoped_ptr<LeakyBucket> leaky_bucket_;
-};
-
-TEST_F(LeakyBucketTest, Basic) {
-  QuicBandwidth draining_rate = QuicBandwidth::FromBytesPerSecond(200000);
-  leaky_bucket_->SetDrainingRate(clock_.Now(), draining_rate);
-  leaky_bucket_->Add(clock_.Now(), 2000);
-  EXPECT_EQ(2000u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-            leaky_bucket_->TimeRemaining(clock_.Now()));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(1000u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(5),
-            leaky_bucket_->TimeRemaining(clock_.Now()));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(0u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_TRUE(leaky_bucket_->TimeRemaining(clock_.Now()).IsZero());
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(0u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_TRUE(leaky_bucket_->TimeRemaining(clock_.Now()).IsZero());
-  leaky_bucket_->Add(clock_.Now(), 2000);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(11));
-  EXPECT_EQ(0u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_TRUE(leaky_bucket_->TimeRemaining(clock_.Now()).IsZero());
-  leaky_bucket_->Add(clock_.Now(), 2000);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  leaky_bucket_->Add(clock_.Now(), 2000);
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(2000u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-            leaky_bucket_->TimeRemaining(clock_.Now()));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(10));
-  EXPECT_EQ(0u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_TRUE(leaky_bucket_->TimeRemaining(clock_.Now()).IsZero());
-}
-
-TEST_F(LeakyBucketTest, ChangeDrainRate) {
-  QuicBandwidth draining_rate = QuicBandwidth::FromBytesPerSecond(200000);
-  leaky_bucket_->SetDrainingRate(clock_.Now(), draining_rate);
-  leaky_bucket_->Add(clock_.Now(), 2000);
-  EXPECT_EQ(2000u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-            leaky_bucket_->TimeRemaining(clock_.Now()));
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  EXPECT_EQ(1000u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(5),
-            leaky_bucket_->TimeRemaining(clock_.Now()));
-  draining_rate = draining_rate.Scale(0.5f);  // Cut drain rate in half.
-  leaky_bucket_->SetDrainingRate(clock_.Now(), draining_rate);
-  EXPECT_EQ(1000u, leaky_bucket_->BytesPending(clock_.Now()));
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(10),
-            leaky_bucket_->TimeRemaining(clock_.Now()));
-}
-
-}  // namespace test
-}  // namespace net
diff --git a/net/quic/congestion_control/pacing_sender.cc b/net/quic/congestion_control/pacing_sender.cc
index 061f6ec..8073c5b 100644
--- a/net/quic/congestion_control/pacing_sender.cc
+++ b/net/quic/congestion_control/pacing_sender.cc
@@ -20,8 +20,11 @@
 
 PacingSender::~PacingSender() {}
 
-void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) {
-  sender_->SetFromConfig(config, is_server);
+void PacingSender::SetFromConfig(const QuicConfig& config,
+                                 bool is_server,
+                                 bool using_pacing) {
+  DCHECK(using_pacing);
+  sender_->SetFromConfig(config, is_server, using_pacing);
 }
 
 void PacingSender::SetNumEmulatedConnections(int num_connections) {
diff --git a/net/quic/congestion_control/pacing_sender.h b/net/quic/congestion_control/pacing_sender.h
index f16172a..4eb3dab 100644
--- a/net/quic/congestion_control/pacing_sender.h
+++ b/net/quic/congestion_control/pacing_sender.h
@@ -35,7 +35,9 @@
   ~PacingSender() override;
 
   // SendAlgorithmInterface methods.
-  void SetFromConfig(const QuicConfig& config, bool is_server) override;
+  void SetFromConfig(const QuicConfig& config,
+                     bool is_server,
+                     bool using_pacing) override;
   void SetNumEmulatedConnections(int num_connections) override;
   void OnCongestionEvent(bool rtt_updated,
                          QuicByteCount bytes_in_flight,
diff --git a/net/quic/congestion_control/rtt_stats.cc b/net/quic/congestion_control/rtt_stats.cc
index dfb50ef..32e3b58 100644
--- a/net/quic/congestion_control/rtt_stats.cc
+++ b/net/quic/congestion_control/rtt_stats.cc
@@ -28,7 +28,7 @@
       min_rtt_(QuicTime::Delta::Zero()),
       smoothed_rtt_(QuicTime::Delta::Zero()),
       mean_deviation_(QuicTime::Delta::Zero()),
-      initial_rtt_us_(kInitialRttMs * base::Time::kMicrosecondsPerMillisecond),
+      initial_rtt_us_(kInitialRttMs * kNumMicrosPerMilli),
       num_min_rtt_samples_remaining_(0),
       recent_min_rtt_window_(QuicTime::Delta::Infinite()) {}
 
diff --git a/net/quic/congestion_control/send_algorithm_interface.cc b/net/quic/congestion_control/send_algorithm_interface.cc
index 7245e33..82f1135 100644
--- a/net/quic/congestion_control/send_algorithm_interface.cc
+++ b/net/quic/congestion_control/send_algorithm_interface.cc
@@ -16,17 +16,23 @@
     const QuicClock* clock,
     const RttStats* rtt_stats,
     CongestionControlType congestion_control_type,
-    QuicConnectionStats* stats) {
+    QuicConnectionStats* stats,
+    QuicPacketCount initial_congestion_window) {
   switch (congestion_control_type) {
     case kCubic:
-      return new TcpCubicSender(clock, rtt_stats,
-                                false /* don't use Reno */,
+      return new TcpCubicSender(clock, rtt_stats, false /* don't use Reno */,
+                                initial_congestion_window,
                                 kMaxTcpCongestionWindow, stats);
     case kReno:
-      return new TcpCubicSender(clock, rtt_stats,
-                                true /* use Reno */,
+      return new TcpCubicSender(clock, rtt_stats, true /* use Reno */,
+                                initial_congestion_window,
                                 kMaxTcpCongestionWindow, stats);
     case kBBR:
+  // TODO(rtenneti): Enable BbrTcpSender.
+#if 0
+      return new BbrTcpSender(clock, rtt_stats, initial_congestion_window,
+                              kMaxTcpCongestionWindow, stats);
+#endif
       LOG(DFATAL) << "BbrTcpSender is not supported.";
       return nullptr;
   }
diff --git a/net/quic/congestion_control/send_algorithm_interface.h b/net/quic/congestion_control/send_algorithm_interface.h
index 4f74628..7195f81 100644
--- a/net/quic/congestion_control/send_algorithm_interface.h
+++ b/net/quic/congestion_control/send_algorithm_interface.h
@@ -29,14 +29,17 @@
   typedef std::vector<std::pair<QuicPacketSequenceNumber, TransmissionInfo>>
       CongestionVector;
 
-  static SendAlgorithmInterface* Create(const QuicClock* clock,
-                                        const RttStats* rtt_stats,
-                                        CongestionControlType type,
-                                        QuicConnectionStats* stats);
+  static SendAlgorithmInterface* Create(
+      const QuicClock* clock,
+      const RttStats* rtt_stats,
+      CongestionControlType type,
+      QuicConnectionStats* stats,
+      QuicPacketCount initial_congestion_window);
 
   virtual ~SendAlgorithmInterface() {}
 
-  virtual void SetFromConfig(const QuicConfig& config, bool is_server) = 0;
+  virtual void SetFromConfig(
+      const QuicConfig& config, bool is_server, bool using_pacing) = 0;
 
   // Sets the number of connections to emulate when doing congestion control,
   // particularly for congestion avoidance.  Can be set any time.
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc
index 5f20597..2d0efd7 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc
@@ -31,6 +31,7 @@
     const QuicClock* clock,
     const RttStats* rtt_stats,
     bool reno,
+    QuicPacketCount initial_tcp_congestion_window,
     QuicPacketCount max_tcp_congestion_window,
     QuicConnectionStats* stats)
     : hybrid_slow_start_(clock),
@@ -43,7 +44,7 @@
       largest_sent_sequence_number_(0),
       largest_acked_sequence_number_(0),
       largest_sent_at_last_cutback_(0),
-      congestion_window_(kDefaultInitialWindow),
+      congestion_window_(initial_tcp_congestion_window),
       previous_congestion_window_(0),
       slowstart_threshold_(max_tcp_congestion_window),
       previous_slowstart_threshold_(0),
@@ -55,20 +56,19 @@
   UMA_HISTOGRAM_COUNTS("Net.QuicSession.FinalTcpCwnd", congestion_window_);
 }
 
-void TcpCubicSender::SetFromConfig(const QuicConfig& config, bool is_server) {
+void TcpCubicSender::SetFromConfig(const QuicConfig& config,
+                                   bool is_server,
+                                   bool using_pacing) {
   if (is_server) {
     if (config.HasReceivedConnectionOptions() &&
         ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
-      // Initial window experiment.  Ignore the initial congestion
-      // window suggested by the client and use the default ICWND of
-      // 10 instead.
-      congestion_window_ = kDefaultInitialWindow;
-    } else if (config.HasReceivedInitialCongestionWindow()) {
-      // Set the initial window size.
-      congestion_window_ = max(kMinimumCongestionWindow,
-          min(kMaxInitialWindow,
-              static_cast<QuicPacketCount>(
-                  config.ReceivedInitialCongestionWindow())));
+      // Initial window experiment.
+      congestion_window_ = 10;
+    }
+    if (using_pacing) {
+      // Disable the ack train mode in hystart when pacing is enabled, since it
+      // may be falsely triggered.
+      hybrid_slow_start_.set_ack_train_detection(false);
     }
   }
 }
diff --git a/net/quic/congestion_control/tcp_cubic_sender.h b/net/quic/congestion_control/tcp_cubic_sender.h
index 7491565..a7507a2 100644
--- a/net/quic/congestion_control/tcp_cubic_sender.h
+++ b/net/quic/congestion_control/tcp_cubic_sender.h
@@ -34,12 +34,15 @@
   TcpCubicSender(const QuicClock* clock,
                  const RttStats* rtt_stats,
                  bool reno,
+                 QuicPacketCount initial_tcp_congestion_window,
                  QuicPacketCount max_tcp_congestion_window,
                  QuicConnectionStats* stats);
   ~TcpCubicSender() override;
 
   // Start implementation of SendAlgorithmInterface.
-  void SetFromConfig(const QuicConfig& config, bool is_server) override;
+  void SetFromConfig(const QuicConfig& config,
+                     bool is_server,
+                     bool using_pacing) override;
   void SetNumEmulatedConnections(int num_connections) override;
   void OnCongestionEvent(bool rtt_updated,
                          QuicByteCount bytes_in_flight,
diff --git a/net/quic/congestion_control/tcp_cubic_sender_test.cc b/net/quic/congestion_control/tcp_cubic_sender_test.cc
index 48a1300..427dd8c 100644
--- a/net/quic/congestion_control/tcp_cubic_sender_test.cc
+++ b/net/quic/congestion_control/tcp_cubic_sender_test.cc
@@ -21,19 +21,22 @@
 namespace net {
 namespace test {
 
-const uint32 kDefaultWindowTCP = kDefaultInitialWindow * kDefaultTCPMSS;
+// TODO(ianswett): A number of theses tests were written with the assumption of
+// an initial CWND of 10. They have carefully calculated values which should be
+// updated to be based on kInitialCongestionWindowInsecure.
+const uint32 kInitialCongestionWindowPackets = 10;
+const uint32 kDefaultWindowTCP =
+    kInitialCongestionWindowPackets * kDefaultTCPMSS;
 const float kRenoBeta = 0.7f;  // Reno backoff factor.
 
-// TODO(ianswett): Remove 10000 once b/10075719 is fixed.
-const QuicPacketCount kDefaultMaxCongestionWindowTCP = 10000;
-
 class TcpCubicSenderPeer : public TcpCubicSender {
  public:
   TcpCubicSenderPeer(const QuicClock* clock,
                      bool reno,
                      QuicPacketCount max_tcp_congestion_window)
       : TcpCubicSender(
-            clock, &rtt_stats_, reno, max_tcp_congestion_window, &stats_) {
+            clock, &rtt_stats_, reno, kInitialCongestionWindowPackets,
+            max_tcp_congestion_window, &stats_) {
   }
 
   QuicPacketCount congestion_window() {
@@ -61,7 +64,7 @@
   TcpCubicSenderTest()
       : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
         sender_(new TcpCubicSenderPeer(&clock_, true,
-                                       kDefaultMaxCongestionWindowTCP)),
+                                       kMaxTcpCongestionWindow)),
         receiver_(new TcpReceiver()),
         sequence_number_(1),
         acked_sequence_number_(0),
@@ -209,7 +212,7 @@
 
 TEST_F(TcpCubicSenderTest, SlowStartAckTrain) {
   sender_->SetNumEmulatedConnections(1);
-  EXPECT_EQ(kDefaultMaxCongestionWindowTCP * kDefaultTCPMSS,
+  EXPECT_EQ(kMaxTcpCongestionWindow * kDefaultTCPMSS,
             sender_->GetSlowStartThreshold());
 
   // Make sure that we fall out of slow start when we send ACK train longer
@@ -305,7 +308,7 @@
 
 TEST_F(TcpCubicSenderTest, NoPRRWhenLessThanOnePacketInFlight) {
   SendAvailableSendWindow();
-  LoseNPackets(kDefaultInitialWindow - 1);
+  LoseNPackets(kInitialCongestionWindowPackets - 1);
   AckNPackets(1);
   // PRR will allow 2 packets for every ack during recovery.
   EXPECT_EQ(2, SendAvailableSendWindow());
@@ -424,7 +427,7 @@
 
 TEST_F(TcpCubicSenderTest, RTOCongestionWindowAndRevert) {
   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  EXPECT_EQ(10000u, sender_->slowstart_threshold());
+  EXPECT_EQ(kMaxTcpCongestionWindow, sender_->slowstart_threshold());
 
   // Expect the window to decrease to the minimum once the RTO fires
   // and slow start threshold to be set to 1/2 of the CWND.
@@ -435,7 +438,7 @@
   // Now repair the RTO and ensure the slowstart threshold reverts.
   sender_->RevertRetransmissionTimeout();
   EXPECT_EQ(kDefaultWindowTCP, sender_->GetCongestionWindow());
-  EXPECT_EQ(10000u, sender_->slowstart_threshold());
+  EXPECT_EQ(kMaxTcpCongestionWindow, sender_->slowstart_threshold());
 }
 
 TEST_F(TcpCubicSenderTest, RTOCongestionWindowNoRetransmission) {
@@ -574,20 +577,26 @@
 }
 
 TEST_F(TcpCubicSenderTest, ConfigureMaxInitialWindow) {
-  QuicPacketCount congestion_window = sender_->congestion_window();
   QuicConfig config;
-  QuicConfigPeer::SetReceivedInitialWindow(&config, 2 * congestion_window);
 
-  sender_->SetFromConfig(config, true);
-  EXPECT_EQ(2 * congestion_window, sender_->congestion_window());
-
-  // Verify that kCOPT: kIW10 forces the congestion window to the
-  // default of 10 regardless of ReceivedInitialWindow.
+  // Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
   QuicTagVector options;
   options.push_back(kIW10);
   QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  sender_->SetFromConfig(config, true);
-  EXPECT_EQ(congestion_window, sender_->congestion_window());
+  sender_->SetFromConfig(config,
+                         /* is_server= */ true,
+                         /* using_pacing= */ false);
+  EXPECT_EQ(10u, sender_->congestion_window());
+}
+
+TEST_F(TcpCubicSenderTest, DisableAckTrainDetectionWithPacing) {
+  EXPECT_TRUE(sender_->hybrid_slow_start().ack_train_detection());
+
+  QuicConfig config;
+  sender_->SetFromConfig(config,
+                         /* is_server= */ true,
+                         /* using_pacing= */ true);
+  EXPECT_FALSE(sender_->hybrid_slow_start().ack_train_detection());
 }
 
 TEST_F(TcpCubicSenderTest, 2ConnectionCongestionAvoidanceAtEndOfRecovery) {
diff --git a/net/quic/crypto/cached_network_parameters.cc b/net/quic/crypto/cached_network_parameters.cc
new file mode 100644
index 0000000..20a438b
--- /dev/null
+++ b/net/quic/crypto/cached_network_parameters.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/crypto/cached_network_parameters.h"
+
+namespace net {
+
+CachedNetworkParameters::CachedNetworkParameters()
+    : bandwidth_estimate_bytes_per_second_(0),
+      max_bandwidth_estimate_bytes_per_second_(0),
+      max_bandwidth_timestamp_seconds_(0),
+      min_rtt_ms_(0),
+      previous_connection_state_(0),
+      timestamp_(0) {
+}
+
+CachedNetworkParameters::~CachedNetworkParameters() {
+}
+
+bool CachedNetworkParameters::operator==(
+    const CachedNetworkParameters& other) const {
+  return serving_region_ == other.serving_region_ &&
+      bandwidth_estimate_bytes_per_second_ ==
+          other.bandwidth_estimate_bytes_per_second_ &&
+      max_bandwidth_estimate_bytes_per_second_ ==
+          other.max_bandwidth_estimate_bytes_per_second_ &&
+      max_bandwidth_timestamp_seconds_ ==
+          other.max_bandwidth_timestamp_seconds_ &&
+      min_rtt_ms_ == other.min_rtt_ms_ &&
+      previous_connection_state_ == other.previous_connection_state_ &&
+      timestamp_ == other.timestamp_;
+}
+
+bool CachedNetworkParameters::operator!=(
+    const CachedNetworkParameters& other) const {
+  return !(*this == other);
+}
+
+}  // namespace net
diff --git a/net/quic/crypto/cached_network_parameters.h b/net/quic/crypto/cached_network_parameters.h
new file mode 100644
index 0000000..5f22070
--- /dev/null
+++ b/net/quic/crypto/cached_network_parameters.h
@@ -0,0 +1,109 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_CRYPTO_CACHED_NETWORK_PARAMETERS_H_
+#define NET_QUIC_CRYPTO_CACHED_NETWORK_PARAMETERS_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/strings/string_piece.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// TODO(rtenneti): sync with server more rationally.
+// CachedNetworkParameters contains data that can be used to choose appropriate
+// connection parameters (initial RTT, initial CWND, etc.) in new connections.
+class NET_EXPORT_PRIVATE CachedNetworkParameters {
+ public:
+  // Describes the state of the connection during which the supplied network
+  // parameters were calculated.
+  enum PreviousConnectionState {
+    SLOW_START = 0,
+    CONGESTION_AVOIDANCE = 1,
+  };
+
+  CachedNetworkParameters();
+  ~CachedNetworkParameters();
+
+  bool operator==(const CachedNetworkParameters& other) const;
+  bool operator!=(const CachedNetworkParameters& other) const;
+
+  std::string serving_region() const {
+    return serving_region_;
+  }
+  void set_serving_region(base::StringPiece serving_region) {
+    serving_region_ = serving_region.as_string();
+  }
+
+  int32 bandwidth_estimate_bytes_per_second() const {
+    return bandwidth_estimate_bytes_per_second_;
+  }
+  void set_bandwidth_estimate_bytes_per_second(
+      int32 bandwidth_estimate_bytes_per_second) {
+    bandwidth_estimate_bytes_per_second_ = bandwidth_estimate_bytes_per_second;
+  }
+
+  int32 max_bandwidth_estimate_bytes_per_second() const {
+    return max_bandwidth_estimate_bytes_per_second_;
+  }
+  void set_max_bandwidth_estimate_bytes_per_second(
+      int32 max_bandwidth_estimate_bytes_per_second) {
+    max_bandwidth_estimate_bytes_per_second_ =
+        max_bandwidth_estimate_bytes_per_second;
+  }
+
+  int64 max_bandwidth_timestamp_seconds() const {
+    return max_bandwidth_timestamp_seconds_;
+  }
+  void set_max_bandwidth_timestamp_seconds(
+      int64 max_bandwidth_timestamp_seconds) {
+    max_bandwidth_timestamp_seconds_ = max_bandwidth_timestamp_seconds;
+  }
+
+  int32 min_rtt_ms() const {
+    return min_rtt_ms_;
+  }
+  void set_min_rtt_ms(int32 min_rtt_ms) {
+    min_rtt_ms_ = min_rtt_ms;
+  }
+
+  int32 previous_connection_state() const {
+    return previous_connection_state_;
+  }
+  void set_previous_connection_state(int32 previous_connection_state) {
+    previous_connection_state_ = previous_connection_state;
+  }
+
+  int64 timestamp() const { return timestamp_; }
+  void set_timestamp(int64 timestamp) { timestamp_ = timestamp; }
+
+ private:
+  // serving_region_ is used to decide whether or not the bandwidth estimate and
+  // min RTT are reasonable and if they should be used.
+  // For example a group of geographically close servers may share the same
+  // serving_region_ string if they are expected to have similar network
+  // performance.
+  std::string serving_region_;
+  // The server can supply a bandwidth estimate (in bytes/s) which it may re-use
+  // on receipt of a source-address token with this field set.
+  int32 bandwidth_estimate_bytes_per_second_;
+  // The maximum bandwidth seen by the client, not necessarily the latest.
+  int32 max_bandwidth_estimate_bytes_per_second_;
+  // Timestamp (seconds since UNIX epoch) that indicates when the max bandwidth
+  // was seen by the server.
+  int64 max_bandwidth_timestamp_seconds_;
+  // The min RTT seen on a previous connection can be used by the server to
+  // inform initial connection parameters for new connections.
+  int32 min_rtt_ms_;
+  // Encodes the PreviousConnectionState enum.
+  int32 previous_connection_state_;
+  // UNIX timestamp when this bandwidth estimate was created.
+  int64 timestamp_;
+};
+
+}  // namespace net
+
+#endif  // NET_QUIC_CRYPTO_CACHED_NETWORK_PARAMETERS_H_
diff --git a/net/quic/crypto/quic_crypto_client_config.cc b/net/quic/crypto/quic_crypto_client_config.cc
index 4828c3a..268c8ee 100644
--- a/net/quic/crypto/quic_crypto_client_config.cc
+++ b/net/quic/crypto/quic_crypto_client_config.cc
@@ -847,8 +847,9 @@
       break;
     }
   }
-  if (i == canonical_suffixes_.size())
+  if (i == canonical_suffixes_.size()) {
     return false;
+  }
 
   QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(),
                                 server_id.is_https(),
diff --git a/net/quic/crypto/quic_crypto_server_config.h b/net/quic/crypto/quic_crypto_server_config.h
index dbbff1a..8a58aea 100644
--- a/net/quic/crypto/quic_crypto_server_config.h
+++ b/net/quic/crypto/quic_crypto_server_config.h
@@ -15,11 +15,11 @@
 #include "base/synchronization/lock.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_export.h"
+#include "net/quic/crypto/cached_network_parameters.h"
 #include "net/quic/crypto/crypto_handshake.h"
 #include "net/quic/crypto/crypto_handshake_message.h"
 #include "net/quic/crypto/crypto_protocol.h"
 #include "net/quic/crypto/crypto_secret_boxer.h"
-#include "net/quic/crypto/source_address_token.h"
 #include "net/quic/quic_time.h"
 
 namespace net {
diff --git a/net/quic/crypto/source_address_token.cc b/net/quic/crypto/source_address_token.cc
index 0b514fe..5faedaa 100644
--- a/net/quic/crypto/source_address_token.cc
+++ b/net/quic/crypto/source_address_token.cc
@@ -11,37 +11,6 @@
 
 namespace net {
 
-CachedNetworkParameters::CachedNetworkParameters()
-    : bandwidth_estimate_bytes_per_second_(0),
-      max_bandwidth_estimate_bytes_per_second_(0),
-      max_bandwidth_timestamp_seconds_(0),
-      min_rtt_ms_(0),
-      previous_connection_state_(0),
-      timestamp_(0) {
-}
-
-CachedNetworkParameters::~CachedNetworkParameters() {
-}
-
-bool CachedNetworkParameters::operator==(
-    const CachedNetworkParameters& other) const {
-  return serving_region_ == other.serving_region_ &&
-      bandwidth_estimate_bytes_per_second_ ==
-          other.bandwidth_estimate_bytes_per_second_ &&
-      max_bandwidth_estimate_bytes_per_second_ ==
-          other.max_bandwidth_estimate_bytes_per_second_ &&
-      max_bandwidth_timestamp_seconds_ ==
-          other.max_bandwidth_timestamp_seconds_ &&
-      min_rtt_ms_ == other.min_rtt_ms_ &&
-      previous_connection_state_ == other.previous_connection_state_ &&
-      timestamp_ == other.timestamp_;
-}
-
-bool CachedNetworkParameters::operator!=(
-    const CachedNetworkParameters& other) const {
-  return !(*this == other);
-}
-
 SourceAddressToken::SourceAddressToken()
     : has_cached_network_parameters_(false) {
 }
diff --git a/net/quic/crypto/source_address_token.h b/net/quic/crypto/source_address_token.h
index 76c3454..f9a5098 100644
--- a/net/quic/crypto/source_address_token.h
+++ b/net/quic/crypto/source_address_token.h
@@ -10,101 +10,11 @@
 #include "base/basictypes.h"
 #include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
+#include "net/quic/crypto/cached_network_parameters.h"
 
 namespace net {
 
 // TODO(rtenneti): sync with server more rationally.
-// CachedNetworkParameters contains data that can be used to choose appropriate
-// connection parameters (initial RTT, initial CWND, etc.) in new connections.
-class NET_EXPORT_PRIVATE CachedNetworkParameters {
- public:
-  // Describes the state of the connection during which the supplied network
-  // parameters were calculated.
-  enum PreviousConnectionState {
-    SLOW_START = 0,
-    CONGESTION_AVOIDANCE = 1,
-  };
-
-  CachedNetworkParameters();
-  ~CachedNetworkParameters();
-
-  bool operator==(const CachedNetworkParameters& other) const;
-  bool operator!=(const CachedNetworkParameters& other) const;
-
-  std::string serving_region() const {
-    return serving_region_;
-  }
-  void set_serving_region(base::StringPiece serving_region) {
-    serving_region_ = serving_region.as_string();
-  }
-
-  int32 bandwidth_estimate_bytes_per_second() const {
-    return bandwidth_estimate_bytes_per_second_;
-  }
-  void set_bandwidth_estimate_bytes_per_second(
-      int32 bandwidth_estimate_bytes_per_second) {
-    bandwidth_estimate_bytes_per_second_ = bandwidth_estimate_bytes_per_second;
-  }
-
-  int32 max_bandwidth_estimate_bytes_per_second() const {
-    return max_bandwidth_estimate_bytes_per_second_;
-  }
-  void set_max_bandwidth_estimate_bytes_per_second(
-      int32 max_bandwidth_estimate_bytes_per_second) {
-    max_bandwidth_estimate_bytes_per_second_ =
-        max_bandwidth_estimate_bytes_per_second;
-  }
-
-  int64 max_bandwidth_timestamp_seconds() const {
-    return max_bandwidth_timestamp_seconds_;
-  }
-  void set_max_bandwidth_timestamp_seconds(
-      int64 max_bandwidth_timestamp_seconds) {
-    max_bandwidth_timestamp_seconds_ = max_bandwidth_timestamp_seconds;
-  }
-
-  int32 min_rtt_ms() const {
-    return min_rtt_ms_;
-  }
-  void set_min_rtt_ms(int32 min_rtt_ms) {
-    min_rtt_ms_ = min_rtt_ms;
-  }
-
-  int32 previous_connection_state() const {
-    return previous_connection_state_;
-  }
-  void set_previous_connection_state(int32 previous_connection_state) {
-    previous_connection_state_ = previous_connection_state;
-  }
-
-  int64 timestamp() const { return timestamp_; }
-  void set_timestamp(int64 timestamp) { timestamp_ = timestamp; }
-
- private:
-  // serving_region_ is used to decide whether or not the bandwidth estimate and
-  // min RTT are reasonable and if they should be used.
-  // For example a group of geographically close servers may share the same
-  // serving_region_ string if they are expected to have similar network
-  // performance.
-  std::string serving_region_;
-  // The server can supply a bandwidth estimate (in bytes/s) which it may re-use
-  // on receipt of a source-address token with this field set.
-  int32 bandwidth_estimate_bytes_per_second_;
-  // The maximum bandwidth seen by the client, not necessarily the latest.
-  int32 max_bandwidth_estimate_bytes_per_second_;
-  // Timestamp (seconds since UNIX epoch) that indicates when the max bandwidth
-  // was seen by the server.
-  int64 max_bandwidth_timestamp_seconds_;
-  // The min RTT seen on a previous connection can be used by the server to
-  // inform initial connection parameters for new connections.
-  int32 min_rtt_ms_;
-  // Encodes the PreviousConnectionState enum.
-  int32 previous_connection_state_;
-  // UNIX timestamp when this bandwidth estimate was created.
-  int64 timestamp_;
-};
-
-// TODO(rtenneti): sync with server more rationally.
 // A SourceAddressToken is serialised, encrypted and sent to clients so that
 // they can prove ownership of an IP address.
 class NET_EXPORT_PRIVATE SourceAddressToken {
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index 73a5aec..274099c 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -155,10 +155,9 @@
     TransportSecurityState* transport_security_state,
     scoped_ptr<QuicServerInfo> server_info,
     const QuicConfig& config,
-    bool is_secure,
     base::TaskRunner* task_runner,
     NetLog* net_log)
-    : QuicClientSessionBase(connection, config, is_secure),
+    : QuicClientSessionBase(connection, config),
       require_confirmation_(false),
       stream_factory_(stream_factory),
       socket_(socket.Pass()),
diff --git a/net/quic/quic_client_session.h b/net/quic/quic_client_session.h
index 6c33eb5..b1a35d9 100644
--- a/net/quic/quic_client_session.h
+++ b/net/quic/quic_client_session.h
@@ -96,7 +96,6 @@
                     TransportSecurityState* transport_security_state,
                     scoped_ptr<QuicServerInfo> server_info,
                     const QuicConfig& config,
-                    bool is_secure,
                     base::TaskRunner* task_runner,
                     NetLog* net_log);
   ~QuicClientSession() override;
diff --git a/net/quic/quic_client_session_base.cc b/net/quic/quic_client_session_base.cc
index 5b5902b..40d4b86 100644
--- a/net/quic/quic_client_session_base.cc
+++ b/net/quic/quic_client_session_base.cc
@@ -10,9 +10,8 @@
 
 QuicClientSessionBase::QuicClientSessionBase(
     QuicConnection* connection,
-    const QuicConfig& config,
-    bool is_secure)
-    : QuicSession(connection, config, is_secure) {}
+    const QuicConfig& config)
+    : QuicSession(connection, config) {}
 
 QuicClientSessionBase::~QuicClientSessionBase() {}
 
diff --git a/net/quic/quic_client_session_base.h b/net/quic/quic_client_session_base.h
index a7f64fb..d72996c 100644
--- a/net/quic/quic_client_session_base.h
+++ b/net/quic/quic_client_session_base.h
@@ -14,8 +14,7 @@
 class NET_EXPORT_PRIVATE QuicClientSessionBase : public QuicSession {
  public:
   QuicClientSessionBase(QuicConnection* connection,
-                        const QuicConfig& config,
-                        bool is_secure);
+                        const QuicConfig& config);
 
   ~QuicClientSessionBase() override;
 
diff --git a/net/quic/quic_client_session_test.cc b/net/quic/quic_client_session_test.cc
index 8860f2e..66583b8 100644
--- a/net/quic/quic_client_session_test.cc
+++ b/net/quic/quic_client_session_test.cc
@@ -46,7 +46,6 @@
         session_(connection_, GetSocket().Pass(), nullptr,
                  &transport_security_state_,
                  make_scoped_ptr((QuicServerInfo*)nullptr), DefaultQuicConfig(),
-                 /*is_secure=*/false,
                  base::MessageLoop::current()->message_loop_proxy().get(),
                  &net_log_) {
     session_.InitializeSession(QuicServerId(kServerHostname, kServerPort,
diff --git a/net/quic/quic_config.cc b/net/quic/quic_config.cc
index b1b7343..622cf3f 100644
--- a/net/quic/quic_config.cc
+++ b/net/quic/quic_config.cc
@@ -434,7 +434,6 @@
       keepalive_timeout_seconds_(kKATO, PRESENCE_OPTIONAL),
       max_streams_per_connection_(kMSPC, PRESENCE_REQUIRED),
       bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
-      initial_congestion_window_(kSWND, PRESENCE_OPTIONAL),
       initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
       // TODO(rjshade): Remove this when retiring QUIC_VERSION_19.
       initial_flow_control_window_bytes_(kIFCW, PRESENCE_OPTIONAL),
@@ -524,18 +523,6 @@
   return bytes_for_connection_id_.GetReceivedValue();
 }
 
-void QuicConfig::SetInitialCongestionWindowToSend(size_t initial_window) {
-  initial_congestion_window_.SetSendValue(initial_window);
-}
-
-bool QuicConfig::HasReceivedInitialCongestionWindow() const {
-  return initial_congestion_window_.HasReceivedValue();
-}
-
-uint32 QuicConfig::ReceivedInitialCongestionWindow() const {
-  return initial_congestion_window_.GetReceivedValue();
-}
-
 void QuicConfig::SetInitialRoundTripTimeUsToSend(size_t rtt) {
   initial_round_trip_time_us_.SetSendValue(rtt);
 }
@@ -675,7 +662,6 @@
   keepalive_timeout_seconds_.ToHandshakeMessage(out);
   max_streams_per_connection_.ToHandshakeMessage(out);
   bytes_for_connection_id_.ToHandshakeMessage(out);
-  initial_congestion_window_.ToHandshakeMessage(out);
   initial_round_trip_time_us_.ToHandshakeMessage(out);
   initial_flow_control_window_bytes_.ToHandshakeMessage(out);
   initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
@@ -712,10 +698,6 @@
         peer_hello, hello_type, error_details);
   }
   if (error == QUIC_NO_ERROR) {
-    error = initial_congestion_window_.ProcessPeerHello(
-        peer_hello, hello_type, error_details);
-  }
-  if (error == QUIC_NO_ERROR) {
     error = initial_round_trip_time_us_.ProcessPeerHello(
         peer_hello, hello_type, error_details);
   }
diff --git a/net/quic/quic_config.h b/net/quic/quic_config.h
index a4d6129..cf3775c 100644
--- a/net/quic/quic_config.h
+++ b/net/quic/quic_config.h
@@ -319,13 +319,6 @@
 
   uint32 ReceivedBytesForConnectionId() const;
 
-  // Sets the peer's default initial congestion window in packets.
-  void SetInitialCongestionWindowToSend(size_t initial_window);
-
-  bool HasReceivedInitialCongestionWindow() const;
-
-  uint32 ReceivedInitialCongestionWindow() const;
-
   // Sets an estimated initial round trip time in us.
   void SetInitialRoundTripTimeUsToSend(size_t rtt_us);
 
@@ -413,8 +406,6 @@
   QuicNegotiableUint32 max_streams_per_connection_;
   // The number of bytes required for the connection ID.
   QuicFixedUint32 bytes_for_connection_id_;
-  // Initial congestion window in packets.
-  QuicFixedUint32 initial_congestion_window_;
   // Initial round trip time estimate in microseconds.
   QuicFixedUint32 initial_round_trip_time_us_;
 
diff --git a/net/quic/quic_config_test.cc b/net/quic/quic_config_test.cc
index 914b137..413d7fb 100644
--- a/net/quic/quic_config_test.cc
+++ b/net/quic/quic_config_test.cc
@@ -81,8 +81,7 @@
       QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
   client_config.SetMaxStreamsPerConnection(
       2 * kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection);
-  client_config.SetInitialRoundTripTimeUsToSend(
-      10 * base::Time::kMicrosecondsPerMillisecond);
+  client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
   client_config.SetInitialFlowControlWindowToSend(
       2 * kInitialSessionFlowControlWindowForTest);
   client_config.SetInitialStreamFlowControlWindowToSend(
@@ -107,8 +106,7 @@
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
             config_.MaxStreamsPerConnection());
   EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.KeepaliveTimeout());
-  EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
-            config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
   EXPECT_TRUE(config_.HasReceivedConnectionOptions());
   EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
   EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kTBBR);
@@ -134,9 +132,7 @@
   server_config.SetMaxStreamsPerConnection(
       kDefaultMaxStreamsPerConnection / 2,
       kDefaultMaxStreamsPerConnection / 2);
-  server_config.SetInitialCongestionWindowToSend(kDefaultInitialWindow / 2);
-  server_config.SetInitialRoundTripTimeUsToSend(
-      10 * base::Time::kMicrosecondsPerMillisecond);
+  server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
   server_config.SetInitialFlowControlWindowToSend(
       2 * kInitialSessionFlowControlWindowForTest);
   server_config.SetInitialStreamFlowControlWindowToSend(
@@ -156,11 +152,8 @@
             config_.IdleConnectionStateLifetime());
   EXPECT_EQ(kDefaultMaxStreamsPerConnection / 2,
             config_.MaxStreamsPerConnection());
-  EXPECT_EQ(kDefaultInitialWindow / 2,
-            config_.ReceivedInitialCongestionWindow());
   EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.KeepaliveTimeout());
-  EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
-            config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
   EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
             2 * kInitialSessionFlowControlWindowForTest);
   EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index 6308d88..fd9ec5f 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -189,6 +189,7 @@
                                const PacketWriterFactory& writer_factory,
                                bool owns_writer,
                                bool is_server,
+                               bool is_secure,
                                const QuicVersionVector& supported_versions)
     : framer_(supported_versions, helper->GetClock()->ApproximateNow(),
               is_server),
@@ -222,9 +223,7 @@
       timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))),
       ping_alarm_(helper->CreateAlarm(new PingAlarm(this))),
       packet_generator_(connection_id_, &framer_, random_generator_, this),
-      idle_network_timeout_(FLAGS_quic_unified_timeouts ?
-          QuicTime::Delta::Infinite() :
-          QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs)),
+      idle_network_timeout_(QuicTime::Delta::Infinite()),
       overall_connection_timeout_(QuicTime::Delta::Infinite()),
       time_of_last_received_packet_(clock_->ApproximateNow()),
       time_of_last_sent_new_packet_(clock_->ApproximateNow()),
@@ -232,7 +231,8 @@
       sent_packet_manager_(
           is_server, clock_, &stats_,
           FLAGS_quic_use_bbr_congestion_control ? kBBR : kCubic,
-          FLAGS_quic_use_time_loss_detection ? kTime : kNack),
+          FLAGS_quic_use_time_loss_detection ? kTime : kNack,
+          is_secure),
       version_negotiation_state_(START_NEGOTIATION),
       is_server_(is_server),
       connected_(true),
@@ -240,12 +240,10 @@
       peer_port_changed_(false),
       self_ip_changed_(false),
       self_port_changed_(false),
-      can_truncate_connection_ids_(true) {
+      can_truncate_connection_ids_(true),
+      is_secure_(is_secure) {
   DVLOG(1) << ENDPOINT << "Created connection with connection_id: "
            << connection_id;
-  if (!FLAGS_quic_unified_timeouts) {
-    timeout_alarm_->Set(clock_->ApproximateNow().Add(idle_network_timeout_));
-  }
   framer_.set_visitor(this);
   framer_.set_received_entropy_calculator(&received_packet_manager_);
   stats_.connection_creation_time = clock_->ApproximateNow();
@@ -266,17 +264,14 @@
 }
 
 void QuicConnection::SetFromConfig(const QuicConfig& config) {
-  if (FLAGS_quic_unified_timeouts) {
-    if (config.negotiated()) {
-      SetNetworkTimeouts(QuicTime::Delta::Infinite(),
-                         config.IdleConnectionStateLifetime());
-    } else {
-      SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
-                         config.max_idle_time_before_crypto_handshake());
-    }
+  if (config.negotiated()) {
+    SetNetworkTimeouts(QuicTime::Delta::Infinite(),
+                       config.IdleConnectionStateLifetime());
   } else {
-    SetIdleNetworkTimeout(config.IdleConnectionStateLifetime());
+    SetNetworkTimeouts(config.max_time_before_crypto_handshake(),
+                       config.max_idle_time_before_crypto_handshake());
   }
+
   sent_packet_manager_.SetFromConfig(config);
   if (FLAGS_allow_truncated_connection_ids_for_quic &&
       config.HasReceivedBytesForConnectionId() &&
@@ -1898,11 +1893,11 @@
   }
 }
 
-size_t QuicConnection::max_packet_length() const {
+QuicByteCount QuicConnection::max_packet_length() const {
   return packet_generator_.max_packet_length();
 }
 
-void QuicConnection::set_max_packet_length(size_t length) {
+void QuicConnection::set_max_packet_length(QuicByteCount length) {
   return packet_generator_.set_max_packet_length(length);
 }
 
@@ -1928,32 +1923,6 @@
                               pending_handshake);
 }
 
-void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) {
-  // Adjust the idle timeout on client and server to prevent clients from
-  // sending requests to servers which have already closed the connection.
-  if (is_server_) {
-    timeout = timeout.Add(QuicTime::Delta::FromSeconds(3));
-  } else if (timeout > QuicTime::Delta::FromSeconds(1)) {
-    timeout = timeout.Subtract(QuicTime::Delta::FromSeconds(1));
-  }
-
-  if (timeout < idle_network_timeout_) {
-    idle_network_timeout_ = timeout;
-    SetTimeoutAlarm();
-  } else {
-    idle_network_timeout_ = timeout;
-  }
-}
-
-void QuicConnection::SetOverallConnectionTimeout(QuicTime::Delta timeout) {
-  if (timeout < overall_connection_timeout_) {
-    overall_connection_timeout_ = timeout;
-    SetTimeoutAlarm();
-  } else {
-    overall_connection_timeout_ = timeout;
-  }
-}
-
 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout,
                                         QuicTime::Delta idle_timeout) {
   LOG_IF(DFATAL, idle_timeout > overall_timeout)
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index f9f8733..96f5cbc 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -251,6 +251,7 @@
                  const PacketWriterFactory& writer_factory,
                  bool owns_writer,
                  bool is_server,
+                 bool is_secure,
                  const QuicVersionVector& supported_versions);
   ~QuicConnection() override;
 
@@ -397,8 +398,8 @@
   QuicConnectionId connection_id() const { return connection_id_; }
   const QuicClock* clock() const { return clock_; }
   QuicRandom* random_generator() const { return random_generator_; }
-  size_t max_packet_length() const;
-  void set_max_packet_length(size_t length);
+  QuicByteCount max_packet_length() const;
+  void set_max_packet_length(QuicByteCount length);
 
   bool connected() const { return connected_; }
 
@@ -425,16 +426,6 @@
   // Returns true if the connection has queued packets or frames.
   bool HasQueuedData() const;
 
-  // TODO(ianswett): Remove when quic_unified_timeouts is removed.
-  // Sets (or resets) the idle state connection timeout. Also, checks and times
-  // out the connection if network timer has expired for |timeout|.
-  void SetIdleNetworkTimeout(QuicTime::Delta timeout);
-
-  // Sets (or resets) the total time delta the connection can be alive for.
-  // Used to limit the time a connection can be alive before crypto handshake
-  // finishes.
-  void SetOverallConnectionTimeout(QuicTime::Delta timeout);
-
   // Sets the overall and idle state connection timeouts.
   void SetNetworkTimeouts(QuicTime::Delta overall_timeout,
                           QuicTime::Delta idle_timeout);
@@ -530,6 +521,9 @@
   QuicPacketSequenceNumber sequence_number_of_last_sent_packet() const {
     return sequence_number_of_last_sent_packet_;
   }
+  const QuicPacketWriter* writer() const { return writer_; }
+
+  bool is_secure() const { return is_secure_; }
 
  protected:
   // Packets which have not been written to the wire.
@@ -567,7 +561,6 @@
   bool SelectMutualVersion(const QuicVersionVector& available_versions);
 
   QuicPacketWriter* writer() { return writer_; }
-  const QuicPacketWriter* writer() const { return writer_; }
 
   bool peer_port_changed() const { return peer_port_changed_; }
 
@@ -702,7 +695,7 @@
   // decrypted.
   bool last_packet_decrypted_;
   bool last_packet_revived_;  // True if the last packet was revived from FEC.
-  size_t last_size_;  // Size of the last received packet.
+  QuicByteCount last_size_;  // Size of the last received packet.
   EncryptionLevel last_decrypted_packet_level_;
   QuicPacketHeader last_header_;
   std::vector<QuicStreamFrame> last_stream_frames_;
@@ -837,6 +830,9 @@
   // version negotiation packet.
   QuicVersionVector server_supported_versions_;
 
+  // True if this is a secure QUIC connection.
+  bool is_secure_;
+
   DISALLOW_COPY_AND_ASSIGN(QuicConnection);
 };
 
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index 66cb89c..4e58dfd 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -408,6 +408,7 @@
                        factory,
                        /* owns_writer= */ false,
                        is_server,
+                       /* is_secure= */ false,
                        SupportedVersions(version)) {
     // Disable tail loss probes for most tests.
     QuicSentPacketManagerPeer::SetMaxTailLossProbes(
@@ -2506,7 +2507,7 @@
 
 TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
   // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   QuicConfig config;
   connection_.SetFromConfig(config);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -2536,7 +2537,7 @@
 
 TEST_P(QuicConnectionTest, Buffer100NonDecryptablePackets) {
   // SetFromConfig is always called after construction from InitializeSession.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   QuicConfig config;
   config.set_max_undecryptable_packets(100);
   connection_.SetFromConfig(config);
@@ -2775,36 +2776,12 @@
 }
 
 TEST_P(QuicConnectionTest, InitialTimeout) {
-  if (!FLAGS_quic_unified_timeouts) {
-    EXPECT_TRUE(connection_.connected());
-    EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
-
-    QuicTime default_timeout = clock_.ApproximateNow().Add(
-        QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs));
-    EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
-    // Simulate the timeout alarm firing.
-    clock_.AdvanceTime(QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs));
-    connection_.GetTimeoutAlarm()->Fire();
-
-    EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_FALSE(connection_.connected());
-
-    EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
-    EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
-    EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
-    EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-    EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-    return;
-  }
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
   EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
 
   // SetFromConfig sets the initial timeouts before negotiation.
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   QuicConfig config;
   connection_.SetFromConfig(config);
   // Subtract a second from the idle timeout on the client side.
@@ -2913,44 +2890,8 @@
 }
 
 TEST_P(QuicConnectionTest, TimeoutAfterSend) {
-  if (!FLAGS_quic_unified_timeouts) {
-    EXPECT_TRUE(connection_.connected());
-
-    QuicTime default_timeout = clock_.ApproximateNow().Add(
-        QuicTime::Delta::FromSeconds(kDefaultIdleTimeoutSecs));
-
-    // When we send a packet, the timeout will change to 5000 +
-    // kDefaultInitialTimeoutSecs.
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-
-    // Send an ack so we don't set the retransmission alarm.
-    SendAckPacketToPeer();
-    EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
-
-    // The original alarm will fire.  We should not time out because we had a
-    // network event at t=5000.  The alarm will reregister.
-    clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(
-        kDefaultIdleTimeoutSecs * 1000000 - 5000));
-    EXPECT_EQ(default_timeout, clock_.ApproximateNow());
-    connection_.GetTimeoutAlarm()->Fire();
-    EXPECT_TRUE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_TRUE(connection_.connected());
-    EXPECT_EQ(default_timeout.Add(QuicTime::Delta::FromMilliseconds(5)),
-              connection_.GetTimeoutAlarm()->deadline());
-
-    // This time, we should time out.
-    EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-    EXPECT_EQ(default_timeout.Add(QuicTime::Delta::FromMilliseconds(5)),
-              clock_.ApproximateNow());
-    connection_.GetTimeoutAlarm()->Fire();
-    EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
-    EXPECT_FALSE(connection_.connected());
-    return;
-  }
   EXPECT_TRUE(connection_.connected());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   QuicConfig config;
   connection_.SetFromConfig(config);
 
@@ -3055,7 +2996,7 @@
 
   // Set up a larger payload than will fit in one packet.
   const string payload(connection_.max_packet_length(), 'a');
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _)).Times(AnyNumber());
 
   // Now send some packets with no truncation.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
diff --git a/net/quic/quic_crypto_server_stream.cc b/net/quic/quic_crypto_server_stream.cc
index dac2087..1d62376 100644
--- a/net/quic/quic_crypto_server_stream.cc
+++ b/net/quic/quic_crypto_server_stream.cc
@@ -6,10 +6,10 @@
 
 #include "base/base64.h"
 #include "crypto/secure_hash.h"
+#include "net/quic/crypto/cached_network_parameters.h"
 #include "net/quic/crypto/crypto_protocol.h"
 #include "net/quic/crypto/crypto_utils.h"
 #include "net/quic/crypto/quic_crypto_server_config.h"
-#include "net/quic/crypto/source_address_token.h"
 #include "net/quic/quic_config.h"
 #include "net/quic/quic_flags.h"
 #include "net/quic/quic_protocol.h"
diff --git a/net/quic/quic_dispatcher.cc b/net/quic/quic_dispatcher.cc
index aede7c2..d27b454 100644
--- a/net/quic/quic_dispatcher.cc
+++ b/net/quic/quic_dispatcher.cc
@@ -352,8 +352,7 @@
   QuicServerSession* session = new QuicServerSession(
       config_,
       CreateQuicConnection(connection_id, server_address, client_address),
-      this,
-      crypto_config_.HasProofSource());
+      this);
   session->InitializeSession(crypto_config_);
   return session;
 }
@@ -368,6 +367,7 @@
                             connection_writer_factory_,
                             /* owns_writer= */ true,
                             /* is_server= */ true,
+                            crypto_config_.HasProofSource(),
                             supported_versions_);
 }
 
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 8d6dd86..47d58ce 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -36,10 +36,6 @@
 // limit.
 bool FLAGS_quic_allow_more_open_streams = false;
 
-// If true, then QUIC connections will set both idle and overall timeouts in a
-// single method.
-bool FLAGS_quic_unified_timeouts = true;
-
 // If true, QUIC will be more resilliant to junk packets with valid connection
 // IDs.
 bool FLAGS_quic_drop_junk_packets = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index d49f47a..a75f79b 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -15,7 +15,6 @@
 NET_EXPORT_PRIVATE extern bool FLAGS_enable_quic_fec;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_bbr_congestion_control;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_more_open_streams;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_unified_timeouts;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_drop_junk_packets;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_allow_bbr;
 NET_EXPORT_PRIVATE extern bool FLAGS_allow_truncated_connection_ids_for_quic;
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index e2487b4..d2a7694 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -978,30 +978,30 @@
 QuicFramer::AckFrameInfo QuicFramer::GetAckFrameInfo(
     const QuicAckFrame& frame) {
   AckFrameInfo ack_info;
-  if (!frame.missing_packets.empty()) {
-    DCHECK_GE(frame.largest_observed, *frame.missing_packets.rbegin());
-    size_t cur_range_length = 0;
-    SequenceNumberSet::const_iterator iter = frame.missing_packets.begin();
-    QuicPacketSequenceNumber last_missing = *iter;
-    ++iter;
-    for (; iter != frame.missing_packets.end(); ++iter) {
-      if (cur_range_length != numeric_limits<uint8>::max() &&
-          *iter == (last_missing + 1)) {
-        ++cur_range_length;
-      } else {
-        ack_info.nack_ranges[last_missing - cur_range_length] =
-            cur_range_length;
-        cur_range_length = 0;
-      }
-      ack_info.max_delta = max(ack_info.max_delta, *iter - last_missing);
-      last_missing = *iter;
-    }
-    // Include the last nack range.
-    ack_info.nack_ranges[last_missing - cur_range_length] = cur_range_length;
-    // Include the range to the largest observed.
-    ack_info.max_delta = max(ack_info.max_delta,
-                             frame.largest_observed - last_missing);
+  if (frame.missing_packets.empty()) {
+    return ack_info;
   }
+  DCHECK_GE(frame.largest_observed, *frame.missing_packets.rbegin());
+  size_t cur_range_length = 0;
+  SequenceNumberSet::const_iterator iter = frame.missing_packets.begin();
+  QuicPacketSequenceNumber last_missing = *iter;
+  ++iter;
+  for (; iter != frame.missing_packets.end(); ++iter) {
+    if (cur_range_length != numeric_limits<uint8>::max() &&
+        *iter == (last_missing + 1)) {
+      ++cur_range_length;
+    } else {
+      ack_info.nack_ranges[last_missing - cur_range_length] = cur_range_length;
+      cur_range_length = 0;
+    }
+    ack_info.max_delta = max(ack_info.max_delta, *iter - last_missing);
+    last_missing = *iter;
+  }
+  // Include the last nack range.
+  ack_info.nack_ranges[last_missing - cur_range_length] = cur_range_length;
+  // Include the range to the largest observed.
+  ack_info.max_delta =
+      max(ack_info.max_delta, frame.largest_observed - last_missing);
   return ack_info;
 }
 
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index db97aac..a172c24 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -65,8 +65,9 @@
                        address,
                        helper,
                        writer_factory,
-                       true  /* owns_writer */,
+                       true   /* owns_writer */,
                        false  /* is_server */,
+                       false  /* is_secure */,
                        versions) {
   }
 
@@ -215,7 +216,7 @@
         WillRepeatedly(Return(QuicTime::Delta::Zero()));
     EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
         Return(QuicBandwidth::Zero()));
-    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _)).Times(AnyNumber());
     helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
                                            &random_generator_));
     TestPacketWriterFactory writer_factory(socket);
@@ -232,7 +233,6 @@
                               &transport_security_state_,
                               make_scoped_ptr((QuicServerInfo*)nullptr),
                               DefaultQuicConfig(),
-                              /*is_secure=*/false,
                               base::MessageLoop::current()->
                                   message_loop_proxy().get(),
                               nullptr));
diff --git a/net/quic/quic_packet_creator.h b/net/quic/quic_packet_creator.h
index 287cde1..bada2c3 100644
--- a/net/quic/quic_packet_creator.h
+++ b/net/quic/quic_packet_creator.h
@@ -212,11 +212,11 @@
     next_sequence_number_length_ = length;
   }
 
-  size_t max_packet_length() const {
+  QuicByteCount max_packet_length() const {
     return max_packet_length_;
   }
 
-  void set_max_packet_length(size_t length) {
+  void set_max_packet_length(QuicByteCount length) {
     // |max_packet_length_| should not be changed mid-packet or mid-FEC group.
     DCHECK(fec_group_.get() == nullptr && queued_frames_.empty());
     max_packet_length_ = length;
@@ -272,7 +272,7 @@
   // packet.
   bool send_version_in_packet_;
   // Maximum length including headers and encryption (UDP payload length.)
-  size_t max_packet_length_;
+  QuicByteCount max_packet_length_;
   // 0 indicates FEC is disabled.
   size_t max_packets_per_fec_group_;
   // Length of connection_id to send over the wire.
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
index 2481ddc..21ab10c 100644
--- a/net/quic/quic_packet_generator.cc
+++ b/net/quic/quic_packet_generator.cc
@@ -357,11 +357,11 @@
   return packet_creator_.sequence_number();
 }
 
-size_t QuicPacketGenerator::max_packet_length() const {
+QuicByteCount QuicPacketGenerator::max_packet_length() const {
   return packet_creator_.max_packet_length();
 }
 
-void QuicPacketGenerator::set_max_packet_length(size_t length) {
+void QuicPacketGenerator::set_max_packet_length(QuicByteCount length) {
   packet_creator_.set_max_packet_length(length);
 }
 
diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h
index 3fec02a..2882aab 100644
--- a/net/quic/quic_packet_generator.h
+++ b/net/quic/quic_packet_generator.h
@@ -177,9 +177,9 @@
   // created.
   QuicPacketSequenceNumber sequence_number() const;
 
-  size_t max_packet_length() const;
+  QuicByteCount max_packet_length() const;
 
-  void set_max_packet_length(size_t length);
+  void set_max_packet_length(QuicByteCount length);
 
   void set_debug_delegate(DebugDelegate* debug_delegate) {
     debug_delegate_ = debug_delegate;
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index ad920d0..00064ff 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -60,8 +60,11 @@
 const QuicByteCount kDefaultTCPMSS = 1460;
 
 // Maximum size of the initial congestion window in packets.
-const QuicPacketCount kDefaultInitialWindow = 10;
 const QuicPacketCount kMaxInitialWindow = 100;
+// We match SPDY's use of 32 when secure (since we'd compete with SPDY).
+const QuicPacketCount kInitialCongestionWindowSecure = 32;
+// Be conservative, and just use double a typical TCP ICWND for HTTP.
+const QuicPacketCount kInitialCongestionWindowInsecure = 20;
 
 // Default size of initial flow control window, for both stream and session.
 const uint32 kDefaultFlowControlSendWindow = 16 * 1024;  // 16 KB
diff --git a/net/quic/quic_reliable_client_stream.cc b/net/quic/quic_reliable_client_stream.cc
index e186b03..68651cb 100644
--- a/net/quic/quic_reliable_client_stream.cc
+++ b/net/quic/quic_reliable_client_stream.cc
@@ -83,7 +83,7 @@
 
 void QuicReliableClientStream::SetDelegate(
     QuicReliableClientStream::Delegate* delegate) {
-  DCHECK((!delegate_ && delegate) || (delegate_ && !delegate));
+  DCHECK(!(delegate_ && delegate));
   delegate_ = delegate;
 }
 
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index 9e2d04f..7978fed 100644
--- a/net/quic/quic_sent_packet_manager.cc
+++ b/net/quic/quic_sent_packet_manager.cc
@@ -34,8 +34,8 @@
 static const int64 kMaxRetransmissionTimeMs = 60000;
 static const size_t kMaxRetransmissions = 10;
 
-// Only exponentially back off the handshake timer 5 times due to a timeout.
-static const size_t kMaxHandshakeRetransmissionBackoffs = 5;
+// Ensure the handshake timer isnt't faster than 10ms.
+// This limits the tenth retransmitted packet to 10s after the initial CHLO.
 static const int64 kMinHandshakeTimeoutMs = 10;
 
 // Sends up to two tail loss probes before firing an RTO,
@@ -49,6 +49,10 @@
 // Number of unpaced packets to send after quiescence.
 static const size_t kInitialUnpacedBurst = 10;
 
+// Fraction of the receive buffer that can be used for encrypted bytes.
+// Allows a 5% overhead for IP and UDP framing, as well as ack only packets.
+static const float kUsableRecieveBufferFraction = 0.95f;
+
 bool HasCryptoHandshake(const TransmissionInfo& transmission_info) {
   if (transmission_info.retransmittable_frames == nullptr) {
     return false;
@@ -66,17 +70,22 @@
     const QuicClock* clock,
     QuicConnectionStats* stats,
     CongestionControlType congestion_control_type,
-    LossDetectionType loss_type)
+    LossDetectionType loss_type,
+    bool is_secure)
     : unacked_packets_(),
       is_server_(is_server),
       clock_(clock),
       stats_(stats),
       debug_delegate_(nullptr),
       network_change_visitor_(nullptr),
-      send_algorithm_(SendAlgorithmInterface::Create(clock,
-                                                     &rtt_stats_,
-                                                     congestion_control_type,
-                                                     stats)),
+      initial_congestion_window_(is_secure ? kInitialCongestionWindowSecure
+                                           : kInitialCongestionWindowInsecure),
+      send_algorithm_(
+          SendAlgorithmInterface::Create(clock,
+                                         &rtt_stats_,
+                                         congestion_control_type,
+                                         stats,
+                                         initial_congestion_window_)),
       loss_algorithm_(LossDetectionInterface::Create(loss_type)),
       n_connection_simulation_(false),
       receive_buffer_bytes_(kDefaultSocketReceiveBuffer),
@@ -116,15 +125,17 @@
       rtt_stats_.set_recent_min_rtt_window(
           QuicTime::Delta::FromSeconds(FLAGS_quic_recent_min_rtt_window_s));
     }
-    send_algorithm_.reset(
-        SendAlgorithmInterface::Create(clock_, &rtt_stats_, kBBR, stats_));
+    send_algorithm_.reset(SendAlgorithmInterface::Create(
+        clock_, &rtt_stats_, kBBR, stats_, initial_congestion_window_));
   }
   if (config.HasReceivedConnectionOptions() &&
       ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) {
-    send_algorithm_.reset(
-        SendAlgorithmInterface::Create(clock_, &rtt_stats_, kReno, stats_));
+    send_algorithm_.reset(SendAlgorithmInterface::Create(
+        clock_, &rtt_stats_, kReno, stats_, initial_congestion_window_));
   }
-  if (HasClientSentConnectionOption(config, kPACE)) {
+  if (HasClientSentConnectionOption(config, kPACE) ||
+      (FLAGS_quic_allow_bbr &&
+       HasClientSentConnectionOption(config, kTBBR))) {
     EnablePacing();
   }
   if (HasClientSentConnectionOption(config, k1CON)) {
@@ -145,7 +156,7 @@
         max(kMinSocketReceiveBuffer,
             static_cast<QuicByteCount>(config.ReceivedSocketReceiveBuffer()));
   }
-  send_algorithm_->SetFromConfig(config, is_server_);
+  send_algorithm_->SetFromConfig(config, is_server_, using_pacing_);
 
   if (network_change_visitor_ != nullptr) {
     network_change_visitor_->OnCongestionWindowChange();
@@ -595,10 +606,7 @@
 
 void QuicSentPacketManager::RetransmitCryptoPackets() {
   DCHECK_EQ(HANDSHAKE_MODE, GetRetransmissionMode());
-  // TODO(ianswett): Typical TCP implementations only retransmit 5 times.
-  consecutive_crypto_retransmission_count_ =
-      min(kMaxHandshakeRetransmissionBackoffs,
-          consecutive_crypto_retransmission_count_ + 1);
+  ++consecutive_crypto_retransmission_count_;
   bool packet_retransmitted = false;
   QuicPacketSequenceNumber sequence_number = unacked_packets_.GetLeastUnacked();
   for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
@@ -757,7 +765,8 @@
   if (pending_timer_transmission_count_ > 0) {
     return QuicTime::Delta::Zero();
   }
-  if (unacked_packets_.bytes_in_flight() >= receive_buffer_bytes_) {
+  if (unacked_packets_.bytes_in_flight() >=
+      kUsableRecieveBufferFraction * receive_buffer_bytes_) {
     return QuicTime::Delta::Infinite();
   }
   return send_algorithm_->TimeUntilSend(
diff --git a/net/quic/quic_sent_packet_manager.h b/net/quic/quic_sent_packet_manager.h
index f82e34b..2a3ea64 100644
--- a/net/quic/quic_sent_packet_manager.h
+++ b/net/quic/quic_sent_packet_manager.h
@@ -93,7 +93,8 @@
                         const QuicClock* clock,
                         QuicConnectionStats* stats,
                         CongestionControlType congestion_control_type,
-                        LossDetectionType loss_type);
+                        LossDetectionType loss_type,
+                        bool is_secure);
   virtual ~QuicSentPacketManager();
 
   virtual void SetFromConfig(const QuicConfig& config);
@@ -351,6 +352,7 @@
   QuicConnectionStats* stats_;
   DebugDelegate* debug_delegate_;
   NetworkChangeVisitor* network_change_visitor_;
+  const QuicPacketCount initial_congestion_window_;
   RttStats rtt_stats_;
   scoped_ptr<SendAlgorithmInterface> send_algorithm_;
   scoped_ptr<LossDetectionInterface> loss_algorithm_;
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index d7a846a..d710120 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -45,7 +45,7 @@
 class QuicSentPacketManagerTest : public ::testing::TestWithParam<bool> {
  protected:
   QuicSentPacketManagerTest()
-      : manager_(true, &clock_, &stats_, kCubic, kNack),
+      : manager_(true, &clock_, &stats_, kCubic, kNack, false),
         send_algorithm_(new StrictMock<MockSendAlgorithm>),
         network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
     QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
@@ -1080,12 +1080,12 @@
 
   // Check the min.
   RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(&manager_);
-  rtt_stats->set_initial_rtt_us(1 * base::Time::kMicrosecondsPerMillisecond);
+  rtt_stats->set_initial_rtt_us(1 * kNumMicrosPerMilli);
   EXPECT_EQ(clock_.Now().Add(QuicTime::Delta::FromMilliseconds(10)),
             manager_.GetRetransmissionTime());
 
   // Test with a standard smoothed RTT.
-  rtt_stats->set_initial_rtt_us(100 * base::Time::kMicrosecondsPerMillisecond);
+  rtt_stats->set_initial_rtt_us(100 * kNumMicrosPerMilli);
 
   QuicTime::Delta srtt =
       QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us());
@@ -1109,12 +1109,12 @@
 
   // Check the min.
   RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(&manager_);
-  rtt_stats->set_initial_rtt_us(1 * base::Time::kMicrosecondsPerMillisecond);
+  rtt_stats->set_initial_rtt_us(1 * kNumMicrosPerMilli);
   EXPECT_EQ(clock_.Now().Add(QuicTime::Delta::FromMilliseconds(10)),
             manager_.GetRetransmissionTime());
 
   // Test with a standard smoothed RTT.
-  rtt_stats->set_initial_rtt_us(100 * base::Time::kMicrosecondsPerMillisecond);
+  rtt_stats->set_initial_rtt_us(100 * kNumMicrosPerMilli);
   QuicTime::Delta srtt =
       QuicTime::Delta::FromMicroseconds(rtt_stats->initial_rtt_us());
   QuicTime::Delta expected_tlp_delay = srtt.Multiply(2);
@@ -1277,7 +1277,7 @@
   QuicTagVector options;
   options.push_back(kTIME);
   QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
   manager_.SetFromConfig(config);
 
@@ -1318,7 +1318,7 @@
   QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
   EXPECT_CALL(*send_algorithm_, SetNumEmulatedConnections(1));
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   manager_.SetFromConfig(config);
 
   QuicSentPacketManagerPeer::SetIsServer(&manager_, false);
@@ -1326,7 +1326,7 @@
   client_config.SetConnectionOptionsToSend(options);
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
   EXPECT_CALL(*send_algorithm_, SetNumEmulatedConnections(1));
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   manager_.SetFromConfig(client_config);
 }
 
@@ -1340,7 +1340,7 @@
   options.push_back(kNCON);
   QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   manager_.SetFromConfig(config);
 
   EXPECT_CALL(*send_algorithm_, SetNumEmulatedConnections(5));
@@ -1354,7 +1354,7 @@
   options.push_back(kNTLP);
   QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   manager_.SetFromConfig(config);
   EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
 }
@@ -1367,7 +1367,7 @@
   QuicSentPacketManagerPeer::SetIsServer(&manager_, false);
   client_config.SetConnectionOptionsToSend(options);
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   manager_.SetFromConfig(client_config);
   EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
 }
@@ -1380,7 +1380,7 @@
   options.push_back(kPACE);
   QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, /* using_pacing= */ true));
   manager_.SetFromConfig(config);
 
   EXPECT_TRUE(manager_.using_pacing());
@@ -1393,7 +1393,7 @@
   // Try to set a size below the minimum and ensure it gets set to the min.
   QuicConfig client_config;
   QuicConfigPeer::SetReceivedSocketReceiveBuffer(&client_config, 1024);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
   manager_.SetFromConfig(client_config);
 
@@ -1417,6 +1417,27 @@
             manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
 }
 
+TEST_F(QuicSentPacketManagerTest, ReceiveWindowLimited) {
+  EXPECT_EQ(kDefaultSocketReceiveBuffer,
+            QuicSentPacketManagerPeer::GetReceiveWindow(&manager_));
+
+  // Ensure the smaller send window only allows 256 * 0.95 packets to be sent.
+  for (QuicPacketSequenceNumber i = 1; i <= 244; ++i) {
+    EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).WillOnce(Return(
+        QuicTime::Delta::Zero()));
+    EXPECT_EQ(QuicTime::Delta::Zero(),
+              manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, BytesInFlight(), i,
+                                               1024, HAS_RETRANSMITTABLE_DATA))
+        .WillOnce(Return(true));
+    SerializedPacket packet(CreatePacket(i, true));
+    manager_.OnPacketSent(&packet, 0, clock_.Now(), 1024,
+                          NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+  }
+  EXPECT_EQ(QuicTime::Delta::Infinite(),
+            manager_.TimeUntilSend(clock_.Now(), HAS_RETRANSMITTABLE_DATA));
+}
+
 TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
   uint32 initial_rtt_us = 325000;
   EXPECT_NE(initial_rtt_us,
@@ -1424,7 +1445,7 @@
 
   QuicConfig config;
   config.SetInitialRoundTripTimeUsToSend(initial_rtt_us);
-  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _));
   EXPECT_CALL(*network_change_visitor_, OnCongestionWindowChange());
   manager_.SetFromConfig(config);
 
diff --git a/net/quic/quic_server_session.cc b/net/quic/quic_server_session.cc
index 7fab509..1d48182 100644
--- a/net/quic/quic_server_session.cc
+++ b/net/quic/quic_server_session.cc
@@ -5,7 +5,7 @@
 #include "net/quic/quic_server_session.h"
 
 #include "base/logging.h"
-#include "net/quic/crypto/source_address_token.h"
+#include "net/quic/crypto/cached_network_parameters.h"
 #include "net/quic/quic_connection.h"
 #include "net/quic/quic_flags.h"
 #include "net/quic/quic_spdy_server_stream.h"
@@ -15,9 +15,8 @@
 
 QuicServerSession::QuicServerSession(const QuicConfig& config,
                                      QuicConnection* connection,
-                                     QuicServerSessionVisitor* visitor,
-                                     bool is_secure)
-    : QuicSession(connection, config, is_secure),
+                                     QuicServerSessionVisitor* visitor)
+    : QuicSession(connection, config),
       visitor_(visitor),
       bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
       last_scup_time_(QuicTime::Zero()),
diff --git a/net/quic/quic_server_session.h b/net/quic/quic_server_session.h
index a402005..43107a0 100644
--- a/net/quic/quic_server_session.h
+++ b/net/quic/quic_server_session.h
@@ -46,8 +46,7 @@
  public:
   QuicServerSession(const QuicConfig& config,
                     QuicConnection* connection,
-                    QuicServerSessionVisitor* visitor,
-                    bool is_secure);
+                    QuicServerSessionVisitor* visitor);
 
   // Override the base class to notify the owner of the connection close.
   void OnConnectionClosed(QuicErrorCode error, bool from_peer) override;
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index 34a668d..2318ab4 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -95,8 +95,7 @@
   QuicSession* session_;
 };
 
-QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config,
-                         bool is_secure)
+QuicSession::QuicSession(QuicConnection* connection, const QuicConfig& config)
     : connection_(connection),
       visitor_shim_(new VisitorShim(this)),
       config_(config),
@@ -106,8 +105,7 @@
       error_(QUIC_NO_ERROR),
       goaway_received_(false),
       goaway_sent_(false),
-      has_pending_handshake_(false),
-      is_secure_(is_secure) {
+      has_pending_handshake_(false) {
   if (connection_->version() == QUIC_VERSION_19) {
     flow_controller_.reset(new QuicFlowController(
         connection_.get(), 0, is_server(), kDefaultFlowControlSendWindow,
@@ -124,10 +122,6 @@
 void QuicSession::InitializeSession() {
   connection_->set_visitor(visitor_shim_.get());
   connection_->SetFromConfig(config_);
-  if (!FLAGS_quic_unified_timeouts && connection_->connected()) {
-    connection_->SetOverallConnectionTimeout(
-        config_.max_time_before_crypto_handshake());
-  }
   headers_stream_.reset(new QuicHeadersStream(this));
 }
 
@@ -569,9 +563,6 @@
       // Discard originally encrypted packets, since they can't be decrypted by
       // the peer.
       connection_->NeuterUnencryptedPackets();
-      if (!FLAGS_quic_unified_timeouts) {
-        connection_->SetOverallConnectionTimeout(QuicTime::Delta::Infinite());
-      }
       if (!FLAGS_quic_allow_more_open_streams) {
         max_open_streams_ = config_.MaxStreamsPerConnection();
       }
diff --git a/net/quic/quic_session.h b/net/quic/quic_session.h
index 6ca9ce0..43f4042 100644
--- a/net/quic/quic_session.h
+++ b/net/quic/quic_session.h
@@ -52,9 +52,7 @@
     HANDSHAKE_CONFIRMED,
   };
 
-  QuicSession(QuicConnection* connection,
-              const QuicConfig& config,
-              bool is_secure);
+  QuicSession(QuicConnection* connection, const QuicConfig& config);
   void InitializeSession();
 
   ~QuicSession() override;
@@ -212,8 +210,8 @@
   bool IsStreamFlowControlBlocked();
 
   // Returns true if this is a secure QUIC session.
-  bool is_secure() const {
-    return is_secure_;
+  bool IsSecure() const {
+    return connection()->is_secure();
   }
 
   size_t get_max_open_streams() const { return max_open_streams_; }
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index edbfbee..d14d875 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -125,9 +125,7 @@
 class TestSession : public QuicSession {
  public:
   explicit TestSession(QuicConnection* connection)
-      : QuicSession(connection,
-                    DefaultQuicConfig(),
-                    false),
+      : QuicSession(connection, DefaultQuicConfig()),
         crypto_stream_(this),
         writev_consumes_all_data_(false) {
     InitializeSession();
@@ -580,8 +578,7 @@
 }
 
 TEST_P(QuicSessionTest, IncreasedTimeoutAfterCryptoHandshake) {
-  EXPECT_EQ((FLAGS_quic_unified_timeouts ?
-             kInitialIdleTimeoutSecs : kDefaultIdleTimeoutSecs) + 3,
+  EXPECT_EQ(kInitialIdleTimeoutSecs + 3,
             QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds());
   CryptoHandshakeMessage msg;
   session_.GetCryptoStream()->OnHandshakeMessage(msg);
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 076797a..32adeda 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -60,16 +60,6 @@
 // The initial receive window size for both streams and sessions.
 const int32 kInitialReceiveWindowSize = 10 * 1024 * 1024;  // 10MB
 
-// The suggested initial congestion windows for a server to use.
-// TODO: This should be tested and optimized, and even better, suggest a window
-// that corresponds to historical bandwidth and min-RTT.
-// Larger initial congestion windows can, if we don't overshoot, reduce latency
-// by avoiding the RTT needed for slow start to double (and re-double) from a
-// default of 10.
-// We match SPDY's use of 32 when secure (since we'd compete with SPDY).
-const int32 kServerSecureInitialCongestionWindow = 32;
-// Be conservative, and just use double a typical TCP  ICWND for HTTP.
-const int32 kServerInecureInitialCongestionWindow = 20;
 // Set the maximum number of undecryptable packets the connection will store.
 const int32 kMaxUndecryptablePackets = 100;
 
@@ -922,15 +912,13 @@
                                                   packet_writer_factory,
                                                   true  /* owns_writer */,
                                                   false  /* is_server */,
+                                                  server_id.is_https(),
                                                   supported_versions_);
   connection->set_max_packet_length(max_packet_length_);
 
   InitializeCachedStateInCryptoConfig(server_id, server_info);
 
   QuicConfig config = config_;
-  config.SetInitialCongestionWindowToSend(
-      server_id.is_https() ? kServerSecureInitialCongestionWindow
-                           : kServerInecureInitialCongestionWindow);
   config.set_max_undecryptable_packets(kMaxUndecryptablePackets);
   config.SetInitialFlowControlWindowToSend(kInitialReceiveWindowSize);
   config.SetInitialStreamFlowControlWindowToSend(kInitialReceiveWindowSize);
@@ -954,7 +942,7 @@
 
   *session = new QuicClientSession(
       connection, socket.Pass(), this, transport_security_state_,
-      server_info.Pass(), config, server_id.is_https(),
+      server_info.Pass(), config,
       base::MessageLoop::current()->message_loop_proxy().get(),
       net_log.net_log());
   all_sessions_[*session] = server_id;  // owning pointer
diff --git a/net/quic/quic_time_wait_list_manager.cc b/net/quic/quic_time_wait_list_manager.cc
index d59cbc4..67d347f 100644
--- a/net/quic/quic_time_wait_list_manager.cc
+++ b/net/quic/quic_time_wait_list_manager.cc
@@ -27,9 +27,8 @@
 
 namespace {
 
-// Time period for which a given connection_id should live in the time-wait
-// state.
-int64 FLAGS_quic_time_wait_list_seconds = 5;
+// Time period for which the connection_id should live in time wait state.
+const int kTimeWaitSeconds = 5;
 
 }  // namespace
 
@@ -40,7 +39,8 @@
  public:
   explicit ConnectionIdCleanUpAlarm(
       QuicTimeWaitListManager* time_wait_list_manager)
-      : time_wait_list_manager_(time_wait_list_manager) {}
+      : time_wait_list_manager_(time_wait_list_manager) {
+  }
 
   QuicTime OnAlarm() override {
     time_wait_list_manager_->CleanUpOldConnectionIds();
@@ -67,7 +67,8 @@
                QuicEncryptedPacket* packet)
       : server_address_(server_address),
         client_address_(client_address),
-        packet_(packet) {}
+        packet_(packet) {
+  }
 
   const IPEndPoint& server_address() const { return server_address_; }
   const IPEndPoint& client_address() const { return client_address_; }
@@ -87,8 +88,7 @@
     QuicConnectionHelperInterface* helper,
     const QuicVersionVector& supported_versions)
     : helper_(helper),
-      kTimeWaitPeriod_(
-          QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)),
+      kTimeWaitPeriod_(QuicTime::Delta::FromSeconds(kTimeWaitSeconds)),
       connection_id_clean_up_alarm_(
           helper_->CreateAlarm(new ConnectionIdCleanUpAlarm(this))),
       writer_(writer),
@@ -276,7 +276,6 @@
       break;
     }
     // This connection_id has lived its age, retire it now.
-    DVLOG(1) << "Retiring " << it->first << " from the time-wait state.";
     delete it->second.close_packet;
     connection_id_map_.erase(it);
   }
diff --git a/net/quic/test_tools/quic_config_peer.cc b/net/quic/test_tools/quic_config_peer.cc
index 7c84001..d0f5bfd 100644
--- a/net/quic/test_tools/quic_config_peer.cc
+++ b/net/quic/test_tools/quic_config_peer.cc
@@ -10,12 +10,6 @@
 namespace test {
 
 // static
-void QuicConfigPeer::SetReceivedInitialWindow(QuicConfig* config,
-                                              size_t initial_window) {
-  config->initial_congestion_window_.SetReceivedValue(initial_window);
-}
-
-// static
 void QuicConfigPeer::SetReceivedSocketReceiveBuffer(
     QuicConfig* config,
     uint32 receive_buffer_bytes) {
diff --git a/net/quic/test_tools/quic_config_peer.h b/net/quic/test_tools/quic_config_peer.h
index 6c5e237..32e6bff 100644
--- a/net/quic/test_tools/quic_config_peer.h
+++ b/net/quic/test_tools/quic_config_peer.h
@@ -15,9 +15,6 @@
 
 class QuicConfigPeer {
  public:
-  static void SetReceivedInitialWindow(QuicConfig* config,
-                                       size_t initial_window);
-
   static void SetReceivedSocketReceiveBuffer(QuicConfig* config,
                                              uint32 receive_buffer_bytes);
 
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index ae3abfe..13e5eb1 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -221,21 +221,10 @@
   clock_.AdvanceTime(delta);
 }
 
-namespace {
-class NiceMockPacketWriterFactory
-    : public QuicConnection::PacketWriterFactory {
- public:
-  NiceMockPacketWriterFactory() {}
-  ~NiceMockPacketWriterFactory() override {}
-
-  QuicPacketWriter* Create(QuicConnection* /*connection*/) const override {
-    return new testing::NiceMock<MockPacketWriter>();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NiceMockPacketWriterFactory);
-};
-}  // namespace
+QuicPacketWriter* NiceMockPacketWriterFactory::Create(
+    QuicConnection* /*connection*/) const {
+  return new testing::NiceMock<MockPacketWriter>();
+}
 
 MockConnection::MockConnection(bool is_server)
     : QuicConnection(kTestConnectionId,
@@ -243,7 +232,21 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     QuicSupportedVersions()),
+      helper_(helper()) {
+}
+
+MockConnection::MockConnection(bool is_server, bool is_secure)
+    : QuicConnection(kTestConnectionId,
+                     IPEndPoint(TestPeerIPAddress(), kTestPort),
+                     new testing::NiceMock<MockHelper>(),
+                     NiceMockPacketWriterFactory(),
+                     /* owns_writer= */ true,
+                     is_server,
+                     is_secure,
+                     QuicSupportedVersions()),
       helper_(helper()) {
 }
 
@@ -253,7 +256,9 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     QuicSupportedVersions()),
       helper_(helper()) {
 }
 
@@ -264,7 +269,9 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     QuicSupportedVersions()),
       helper_(helper()) {
 }
 
@@ -275,7 +282,9 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, supported_versions),
+                     is_server,
+                     /* is_secure= */ false,
+                     supported_versions),
       helper_(helper()) {
 }
 
@@ -316,7 +325,7 @@
 }
 
 MockSession::MockSession(QuicConnection* connection)
-    : QuicSession(connection, DefaultQuicConfig(), /*is_secure=*/false) {
+    : QuicSession(connection, DefaultQuicConfig()) {
   InitializeSession();
   ON_CALL(*this, WritevData(_, _, _, _, _, _))
       .WillByDefault(testing::Return(QuicConsumedData(0, false)));
@@ -326,7 +335,7 @@
 }
 
 TestSession::TestSession(QuicConnection* connection, const QuicConfig& config)
-    : QuicSession(connection, config, /*is_secure=*/false),
+    : QuicSession(connection, config),
       crypto_stream_(nullptr) {
   InitializeSession();
 }
@@ -343,7 +352,7 @@
 
 TestClientSession::TestClientSession(QuicConnection* connection,
                                      const QuicConfig& config)
-    : QuicClientSessionBase(connection, config, /*is_secure=*/false),
+    : QuicClientSessionBase(connection, config),
       crypto_stream_(nullptr) {
   EXPECT_CALL(*this, OnProofValid(_)).Times(AnyNumber());
   InitializeSession();
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index ea5e5ef..fa987de 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -265,11 +265,25 @@
   DISALLOW_COPY_AND_ASSIGN(MockHelper);
 };
 
+class NiceMockPacketWriterFactory : public QuicConnection::PacketWriterFactory {
+ public:
+  NiceMockPacketWriterFactory() {}
+  ~NiceMockPacketWriterFactory() override {}
+
+  QuicPacketWriter* Create(QuicConnection* /*connection*/) const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NiceMockPacketWriterFactory);
+};
+
 class MockConnection : public QuicConnection {
  public:
   // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
   explicit MockConnection(bool is_server);
 
+  // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
+  MockConnection(bool is_server, bool is_secure);
+
   // Uses a MockHelper, ConnectionId of 42.
   MockConnection(IPEndPoint address, bool is_server);
 
@@ -437,7 +451,9 @@
   MockSendAlgorithm();
   virtual ~MockSendAlgorithm();
 
-  MOCK_METHOD2(SetFromConfig, void(const QuicConfig& config, bool is_server));
+  MOCK_METHOD3(SetFromConfig, void(const QuicConfig& config,
+                                   bool is_server,
+                                   bool using_pacing));
   MOCK_METHOD1(SetNumEmulatedConnections, void(int num_connections));
   MOCK_METHOD1(SetMaxPacketSize, void(QuicByteCount max_packet_size));
   MOCK_METHOD2(OnIncomingQuicCongestionFeedbackFrame,
diff --git a/net/socket/tcp_socket_libevent.cc b/net/socket/tcp_socket_libevent.cc
index cc23765..d7fa9fa 100644
--- a/net/socket/tcp_socket_libevent.cc
+++ b/net/socket/tcp_socket_libevent.cc
@@ -21,6 +21,7 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
+#include "net/base/network_activity_monitor.h"
 #include "net/base/network_change_notifier.h"
 #include "net/socket/socket_libevent.h"
 #include "net/socket/socket_net_log_params.h"
@@ -601,6 +602,8 @@
   read_bytes.Add(rv);
   net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv,
                                 buf->data());
+  NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv);
+
   return rv;
 }
 
@@ -633,6 +636,7 @@
   write_bytes.Add(rv);
   net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv,
                                 buf->data());
+  NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv);
   return rv;
 }
 
diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc
index fd3c8b7..0c3d26f 100644
--- a/net/socket/tcp_socket_win.cc
+++ b/net/socket/tcp_socket_win.cc
@@ -18,6 +18,7 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
+#include "net/base/network_activity_monitor.h"
 #include "net/base/network_change_notifier.h"
 #include "net/base/winsock_init.h"
 #include "net/base/winsock_util.h"
@@ -545,6 +546,7 @@
       write_bytes.Add(rv);
       net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, rv,
                                     buf->data());
+      NetworkActivityMonitor::GetInstance()->IncrementBytesSent(rv);
       return rv;
     }
   } else {
@@ -913,6 +915,7 @@
       read_bytes.Add(rv);
     net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, rv,
                                   buf->data());
+    NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(rv);
     return rv;
   }
 
@@ -982,6 +985,7 @@
       write_bytes.Add(num_bytes);
       net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_SENT, num_bytes,
                                     core_->write_iobuffer_->data());
+      NetworkActivityMonitor::GetInstance()->IncrementBytesSent(num_bytes);
     }
   }
 
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 1fb3e79..33f30fc 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -920,11 +920,10 @@
   EXPECT_EQ(2u, client_negotiated_config->MaxStreamsPerConnection());
 }
 
-TEST_P(EndToEndTest, LimitCongestionWindowAndRTT) {
-  // Client tries to request twice the server's max initial window, and the
-  // server limits it to the max.
-  client_config_.SetInitialCongestionWindowToSend(2 * kMaxInitialWindow);
-  client_config_.SetInitialRoundTripTimeUsToSend(20000);
+TEST_P(EndToEndTest, ClientSuggestsRTT) {
+  // Client suggests initial RTT, verify it is used.
+  const uint32 kInitialRTT = 20000;
+  client_config_.SetInitialRoundTripTimeUsToSend(kInitialRTT);
 
   ASSERT_TRUE(Initialize());
   client_->client()->WaitForCryptoHandshakeConfirmed();
@@ -940,33 +939,21 @@
   const QuicSentPacketManager& server_sent_packet_manager =
       *GetSentPacketManagerFromFirstServerSession();
 
-  // The client shouldn't set its initial window based on the negotiated value.
-  EXPECT_EQ(kDefaultInitialWindow,
-            client_sent_packet_manager.GetCongestionWindowInTcpMss());
-  EXPECT_EQ(kMaxInitialWindow,
-            server_sent_packet_manager.GetCongestionWindowInTcpMss());
+  // BBR automatically enables pacing.
+  EXPECT_EQ(GetParam().use_pacing ||
+            (FLAGS_quic_allow_bbr &&
+             GetParam().congestion_control_tag == kTBBR),
+            server_sent_packet_manager.using_pacing());
+  EXPECT_EQ(GetParam().use_pacing ||
+            (FLAGS_quic_allow_bbr &&
+             GetParam().congestion_control_tag == kTBBR),
+            client_sent_packet_manager.using_pacing());
 
-  EXPECT_EQ(GetParam().use_pacing, server_sent_packet_manager.using_pacing());
-  EXPECT_EQ(GetParam().use_pacing, client_sent_packet_manager.using_pacing());
-
-  // The client *should* set the intitial RTT, but it's increased to 10ms.
-  EXPECT_EQ(20000u, client_sent_packet_manager.GetRttStats()->initial_rtt_us());
-  EXPECT_EQ(20000u, server_sent_packet_manager.GetRttStats()->initial_rtt_us());
-
-  // Now use the negotiated limits with packet loss.
-  SetPacketLossPercentage(30);
-
-  // 10 KB body.
-  string body;
-  GenerateBody(&body, 1024 * 10);
-
-  HTTPMessage request(HttpConstants::HTTP_1_1,
-                      HttpConstants::POST, "/foo");
-  request.AddBody(body, true);
-
+  EXPECT_EQ(kInitialRTT,
+            client_sent_packet_manager.GetRttStats()->initial_rtt_us());
+  EXPECT_EQ(kInitialRTT,
+            server_sent_packet_manager.GetRttStats()->initial_rtt_us());
   server_thread_->Resume();
-
-  EXPECT_EQ(kFooResponseBody, client_->SendCustomSynchronousRequest(request));
 }
 
 TEST_P(EndToEndTest, MaxInitialRTT) {
@@ -1025,7 +1012,7 @@
   EXPECT_FALSE(
       client_sent_packet_manager.GetRttStats()->smoothed_rtt().IsInfinite());
   // Expect the default rtt of 100ms.
-  EXPECT_EQ(static_cast<int64>(100 * base::Time::kMicrosecondsPerMillisecond),
+  EXPECT_EQ(static_cast<int64>(100 * kNumMicrosPerMilli),
             server_sent_packet_manager.GetRttStats()->initial_rtt_us());
   // Ensure the bandwidth is valid.
   client_sent_packet_manager.BandwidthEstimate();
diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc
index b28ec2b..74874d7 100644
--- a/net/tools/quic/quic_client.cc
+++ b/net/tools/quic/quic_client.cc
@@ -199,8 +199,8 @@
                          factory,
                          /* owns_writer= */ false,
                          /* is_server= */ false,
-                         supported_versions_),
-      server_id_.is_https()));
+                         server_id_.is_https(),
+                         supported_versions_)));
 
   // Reset |writer_| after |session_| so that the old writer outlives the old
   // session.
diff --git a/net/tools/quic/quic_client_session.cc b/net/tools/quic/quic_client_session.cc
index 87ca0ce..235eeb0 100644
--- a/net/tools/quic/quic_client_session.cc
+++ b/net/tools/quic/quic_client_session.cc
@@ -15,9 +15,8 @@
 namespace tools {
 
 QuicClientSession::QuicClientSession(const QuicConfig& config,
-                                     QuicConnection* connection,
-                                     bool is_secure)
-    : QuicClientSessionBase(connection, config, is_secure) {
+                                     QuicConnection* connection)
+    : QuicClientSessionBase(connection, config) {
 }
 
 QuicClientSession::~QuicClientSession() {
@@ -26,18 +25,16 @@
 void QuicClientSession::InitializeSession(
     const QuicServerId& server_id,
     QuicCryptoClientConfig* crypto_config) {
-  QuicClientSessionBase::InitializeSession();
   crypto_stream_.reset(
       new QuicCryptoClientStream(server_id, this, nullptr, crypto_config));
+  QuicClientSessionBase::InitializeSession();
 }
 
 void QuicClientSession::OnProofValid(
-    const QuicCryptoClientConfig::CachedState& /*cached*/) {
-}
+    const QuicCryptoClientConfig::CachedState& /*cached*/) {}
 
 void QuicClientSession::OnProofVerifyDetailsAvailable(
-    const ProofVerifyDetails& /*verify_details*/) {
-}
+    const ProofVerifyDetails& /*verify_details*/) {}
 
 QuicSpdyClientStream* QuicClientSession::CreateOutgoingDataStream() {
   if (!crypto_stream_->encryption_established()) {
diff --git a/net/tools/quic/quic_client_session.h b/net/tools/quic/quic_client_session.h
index d1cd38c..3c92efa 100644
--- a/net/tools/quic/quic_client_session.h
+++ b/net/tools/quic/quic_client_session.h
@@ -25,9 +25,7 @@
 
 class QuicClientSession : public QuicClientSessionBase {
  public:
-  QuicClientSession(const QuicConfig& config,
-                    QuicConnection* connection,
-                    bool is_secure);
+  QuicClientSession(const QuicConfig& config, QuicConnection* connection);
   ~QuicClientSession() override;
 
   void InitializeSession(const QuicServerId& server_id,
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc
index 61422e1..5b5c415 100644
--- a/net/tools/quic/quic_client_session_test.cc
+++ b/net/tools/quic/quic_client_session_test.cc
@@ -42,8 +42,7 @@
   ToolsQuicClientSessionTest()
       : connection_(
             new PacketSavingConnection(false, SupportedVersions(GetParam()))) {
-    session_.reset(new QuicClientSession(DefaultQuicConfig(), connection_,
-                                         /*is_secure=*/false));
+    session_.reset(new QuicClientSession(DefaultQuicConfig(), connection_));
     session_->InitializeSession(
         QuicServerId(kServerHostname, kPort, false, PRIVACY_MODE_DISABLED),
         &crypto_config_);
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index 16cee2b..4ea48e9 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -364,8 +364,7 @@
   QuicServerSession* session = new QuicServerSession(
       config_,
       CreateQuicConnection(connection_id, server_address, client_address),
-      this,
-      crypto_config_.HasProofSource());
+      this);
   session->InitializeSession(crypto_config_);
   return session;
 }
@@ -380,6 +379,7 @@
                             connection_writer_factory_,
                             /* owns_writer= */ true,
                             /* is_server= */ true,
+                            crypto_config_.HasProofSource(),
                             supported_versions_);
 }
 
diff --git a/net/tools/quic/quic_server_session.cc b/net/tools/quic/quic_server_session.cc
index 1dd5748..45c1379 100644
--- a/net/tools/quic/quic_server_session.cc
+++ b/net/tools/quic/quic_server_session.cc
@@ -5,7 +5,7 @@
 #include "net/tools/quic/quic_server_session.h"
 
 #include "base/logging.h"
-#include "net/quic/crypto/source_address_token.h"
+#include "net/quic/crypto/cached_network_parameters.h"
 #include "net/quic/quic_connection.h"
 #include "net/quic/quic_flags.h"
 #include "net/quic/reliable_quic_stream.h"
@@ -16,9 +16,8 @@
 
 QuicServerSession::QuicServerSession(const QuicConfig& config,
                                      QuicConnection* connection,
-                                     QuicServerSessionVisitor* visitor,
-                                     bool is_secure)
-    : QuicSession(connection, config, is_secure),
+                                     QuicServerSessionVisitor* visitor)
+    : QuicSession(connection, config),
       visitor_(visitor),
       bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
       last_scup_time_(QuicTime::Zero()),
diff --git a/net/tools/quic/quic_server_session.h b/net/tools/quic/quic_server_session.h
index cdc2bf3..603ad35 100644
--- a/net/tools/quic/quic_server_session.h
+++ b/net/tools/quic/quic_server_session.h
@@ -47,8 +47,7 @@
  public:
   QuicServerSession(const QuicConfig& config,
                     QuicConnection* connection,
-                    QuicServerSessionVisitor* visitor,
-                    bool is_secure);
+                    QuicServerSessionVisitor* visitor);
 
   // Override the base class to notify the owner of the connection close.
   void OnConnectionClosed(QuicErrorCode error, bool from_peer) override;
diff --git a/net/tools/quic/quic_server_session_test.cc b/net/tools/quic/quic_server_session_test.cc
index 202022f..6a17f53 100644
--- a/net/tools/quic/quic_server_session_test.cc
+++ b/net/tools/quic/quic_server_session_test.cc
@@ -4,9 +4,9 @@
 
 #include "net/tools/quic/quic_server_session.h"
 
+#include "net/quic/crypto/cached_network_parameters.h"
 #include "net/quic/crypto/quic_crypto_server_config.h"
 #include "net/quic/crypto/quic_random.h"
-#include "net/quic/crypto/source_address_token.h"
 #include "net/quic/quic_connection.h"
 #include "net/quic/quic_crypto_server_stream.h"
 #include "net/quic/quic_flags.h"
@@ -79,8 +79,7 @@
 
     connection_ =
         new StrictMock<MockConnection>(true, SupportedVersions(GetParam()));
-    session_.reset(new QuicServerSession(config_, connection_, &owner_,
-                                         /*is_secure=*/false));
+    session_.reset(new QuicServerSession(config_, connection_, &owner_));
     MockClock clock;
     handshake_message_.reset(crypto_config_.AddDefaultConfig(
         QuicRandom::GetInstance(), &clock,
diff --git a/net/tools/quic/quic_spdy_client_stream_test.cc b/net/tools/quic/quic_spdy_client_stream_test.cc
index d2106d9..090e2da 100644
--- a/net/tools/quic/quic_spdy_client_stream_test.cc
+++ b/net/tools/quic/quic_spdy_client_stream_test.cc
@@ -29,7 +29,7 @@
   QuicSpdyClientStreamTest()
       : connection_(new StrictMock<MockConnection>(
             false, SupportedVersions(GetParam()))),
-        session_(DefaultQuicConfig(), connection_, /*is_secure=*/false),
+        session_(DefaultQuicConfig(), connection_),
         body_("hello world") {
     session_.InitializeSession(
         QuicServerId("example.com", 80, false, PRIVACY_MODE_DISABLED),
diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc
index 58f50fe..f54a465 100644
--- a/net/tools/quic/quic_time_wait_list_manager.cc
+++ b/net/tools/quic/quic_time_wait_list_manager.cc
@@ -28,9 +28,8 @@
 
 namespace {
 
-// Time period for which a given connection_id should live in the time-wait
-// state.
-int64 FLAGS_quic_time_wait_list_seconds = 5;
+// Time period for which the connection_id should live in time wait state.
+const int kTimeWaitSeconds = 5;
 
 }  // namespace
 
@@ -91,8 +90,7 @@
     EpollServer* epoll_server,
     const QuicVersionVector& supported_versions)
     : epoll_server_(epoll_server),
-      kTimeWaitPeriod_(
-          QuicTime::Delta::FromSeconds(FLAGS_quic_time_wait_list_seconds)),
+      kTimeWaitPeriod_(QuicTime::Delta::FromSeconds(kTimeWaitSeconds)),
       connection_id_clean_up_alarm_(new ConnectionIdCleanUpAlarm(this)),
       clock_(epoll_server_),
       writer_(writer),
@@ -122,7 +120,9 @@
     delete it->second.close_packet;
     connection_id_map_.erase(it);
   }
-  ConnectionIdData data(num_packets, version, clock_.ApproximateNow(),
+  ConnectionIdData data(num_packets,
+                        version,
+                        clock_.ApproximateNow(),
                         close_packet);
   connection_id_map_.insert(make_pair(connection_id, data));
 }
@@ -168,12 +168,12 @@
     return;
   }
   if (it->second.close_packet) {
-     QueuedPacket* queued_packet =
-         new QueuedPacket(server_address,
-                          client_address,
-                          it->second.close_packet->Clone());
-     // Takes ownership of the packet.
-     SendOrQueuePacket(queued_packet);
+    QueuedPacket* queued_packet =
+        new QueuedPacket(server_address,
+                         client_address,
+                         it->second.close_packet->Clone());
+    // Takes ownership of the packet.
+    SendOrQueuePacket(queued_packet);
   } else {
     SendPublicReset(server_address,
                     client_address,
@@ -282,7 +282,6 @@
       break;
     }
     // This connection_id has lived its age, retire it now.
-    DVLOG(1) << "Retiring " << it->first << " from the time-wait state.";
     delete it->second.close_packet;
     connection_id_map_.erase(it);
   }
diff --git a/net/tools/quic/test_tools/quic_test_utils.cc b/net/tools/quic/test_tools/quic_test_utils.cc
index 40b7e88..91cd003 100644
--- a/net/tools/quic/test_tools/quic_test_utils.cc
+++ b/net/tools/quic/test_tools/quic_test_utils.cc
@@ -18,21 +18,10 @@
 namespace tools {
 namespace test {
 
-namespace {
-class NiceMockPacketWriterFactory
-    : public QuicConnection::PacketWriterFactory {
- public:
-  NiceMockPacketWriterFactory() {}
-  ~NiceMockPacketWriterFactory() override {}
-
-  QuicPacketWriter* Create(QuicConnection* /*connection*/) const override {
-    return new testing::NiceMock<MockPacketWriter>();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NiceMockPacketWriterFactory);
-};
-}  // namespace
+QuicPacketWriter* NiceMockPacketWriterFactory::Create(
+    QuicConnection* /*connection*/) const {
+  return new testing::NiceMock<MockPacketWriter>();
+}
 
 MockConnection::MockConnection(bool is_server)
     : QuicConnection(kTestConnectionId,
@@ -40,7 +29,21 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     QuicSupportedVersions()),
+      helper_(helper()) {
+}
+
+MockConnection::MockConnection(bool is_server, bool is_secure)
+    : QuicConnection(kTestConnectionId,
+                     IPEndPoint(net::test::Loopback4(), kTestPort),
+                     new testing::NiceMock<MockHelper>(),
+                     NiceMockPacketWriterFactory(),
+                     /* owns_writer= */ true,
+                     is_server,
+                     is_secure,
+                     QuicSupportedVersions()),
       helper_(helper()) {
 }
 
@@ -50,7 +53,9 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     QuicSupportedVersions()),
       helper_(helper()) {
 }
 
@@ -61,7 +66,9 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     QuicSupportedVersions()),
       helper_(helper()) {
 }
 
@@ -72,7 +79,9 @@
                      new testing::NiceMock<MockHelper>(),
                      NiceMockPacketWriterFactory(),
                      /* owns_writer= */ true,
-                     is_server, QuicSupportedVersions()),
+                     is_server,
+                     /* is_secure= */ false,
+                     supported_versions),
       helper_(helper()) {
 }
 
@@ -93,9 +102,8 @@
   return ack;
 }
 
-TestSession::TestSession(QuicConnection* connection,
-                         const QuicConfig& config)
-    : QuicSession(connection, config, /*is_secure=*/false),
+TestSession::TestSession(QuicConnection* connection, const QuicConfig& config)
+    : QuicSession(connection, config),
       crypto_stream_(nullptr) {
   InitializeSession();
 }
diff --git a/net/tools/quic/test_tools/quic_test_utils.h b/net/tools/quic/test_tools/quic_test_utils.h
index cbd7fbe..9db9fb5 100644
--- a/net/tools/quic/test_tools/quic_test_utils.h
+++ b/net/tools/quic/test_tools/quic_test_utils.h
@@ -39,11 +39,25 @@
 QuicAckFrame MakeAckFrameWithNackRanges(size_t num_nack_ranges,
                                         QuicPacketSequenceNumber least_unacked);
 
+class NiceMockPacketWriterFactory : public QuicConnection::PacketWriterFactory {
+ public:
+  NiceMockPacketWriterFactory() {}
+  ~NiceMockPacketWriterFactory() override {}
+
+  QuicPacketWriter* Create(QuicConnection* /*connection*/) const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NiceMockPacketWriterFactory);
+};
+
 class MockConnection : public QuicConnection {
  public:
   // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
   explicit MockConnection(bool is_server);
 
+  // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
+  MockConnection(bool is_server, bool is_secure);
+
   // Uses a MockHelper, ConnectionId of 42.
   MockConnection(IPEndPoint address, bool is_server);
 
@@ -83,10 +97,12 @@
   void ReallyProcessUdpPacket(const IPEndPoint& self_address,
                               const IPEndPoint& peer_address,
                               const QuicEncryptedPacket& packet) {
-    return QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
+    QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
   }
 
-  virtual bool OnProtocolVersionMismatch(QuicVersion version) { return false; }
+  virtual bool OnProtocolVersionMismatch(QuicVersion version) override {
+    return false;
+  }
 
  private:
   scoped_ptr<QuicConnectionHelperInterface> helper_;
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
index 9b1a995..2dffff3 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -24,6 +24,7 @@
 #include "net/base/net_errors.h"
 #include "net/base/net_log.h"
 #include "net/base/net_util.h"
+#include "net/base/network_activity_monitor.h"
 #include "net/socket/socket_descriptor.h"
 #include "net/udp/udp_net_log_parameters.h"
 
@@ -414,6 +415,7 @@
 
   base::StatsCounter read_bytes("udp.read_bytes");
   read_bytes.Add(result);
+  NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result);
 }
 
 int UDPSocketLibevent::CreateSocket(int addr_family) {
@@ -458,6 +460,7 @@
 
   base::StatsCounter write_bytes("udp.write_bytes");
   write_bytes.Add(result);
+  NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result);
 }
 
 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len,
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
index 4c307fd..11c731f 100644
--- a/net/udp/udp_socket_win.cc
+++ b/net/udp/udp_socket_win.cc
@@ -20,6 +20,7 @@
 #include "net/base/net_errors.h"
 #include "net/base/net_log.h"
 #include "net/base/net_util.h"
+#include "net/base/network_activity_monitor.h"
 #include "net/base/winsock_init.h"
 #include "net/base/winsock_util.h"
 #include "net/socket/socket_descriptor.h"
@@ -595,6 +596,7 @@
 
   base::StatsCounter read_bytes("udp.read_bytes");
   read_bytes.Add(result);
+  NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result);
 }
 
 void UDPSocketWin::DidCompleteWrite() {
@@ -626,6 +628,7 @@
 
   base::StatsCounter write_bytes("udp.write_bytes");
   write_bytes.Add(result);
+  NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result);
 }
 
 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len,
diff --git a/net/url_request/sdch_dictionary_fetcher.cc b/net/url_request/sdch_dictionary_fetcher.cc
index 5806193..5ac65ef 100644
--- a/net/url_request/sdch_dictionary_fetcher.cc
+++ b/net/url_request/sdch_dictionary_fetcher.cc
@@ -11,6 +11,7 @@
 #include "base/compiler_specific.h"
 #include "base/thread_task_runner_handle.h"
 #include "net/base/load_flags.h"
+#include "net/base/sdch_net_log_params.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_status.h"
 #include "net/url_request/url_request_throttler_manager.h"
@@ -45,16 +46,15 @@
   // Avoid pushing duplicate copy onto queue. We may fetch this url again later
   // and get a different dictionary, but there is no reason to have it in the
   // queue twice at one time.
-  if (!fetch_queue_.empty() && fetch_queue_.back() == dictionary_url) {
+  if ((!fetch_queue_.empty() && fetch_queue_.back() == dictionary_url) ||
+      attempted_load_.find(dictionary_url) != attempted_load_.end()) {
+    // TODO(rdsmith): log this error to the net log of the URLRequest
+    // initiating this fetch, once URLRequest will be passed here.
     SdchManager::SdchErrorRecovery(
-        SdchManager::DICTIONARY_ALREADY_SCHEDULED_TO_DOWNLOAD);
+        SDCH_DICTIONARY_PREVIOUSLY_SCHEDULED_TO_DOWNLOAD);
     return;
   }
-  if (attempted_load_.find(dictionary_url) != attempted_load_.end()) {
-    SdchManager::SdchErrorRecovery(
-        SdchManager::DICTIONARY_ALREADY_TRIED_TO_DOWNLOAD);
-    return;
-  }
+
   attempted_load_.insert(dictionary_url);
   fetch_queue_.push(dictionary_url);
 
@@ -166,6 +166,7 @@
 
   next_state_ = STATE_REQUEST_STARTED;
   current_request_->Start();
+  current_request_->net_log().AddEvent(NetLog::TYPE_SDCH_DICTIONARY_FETCH);
 
   return OK;
 }
@@ -207,7 +208,12 @@
       // an infinite loop.  It's not clear how to handle a read failure
       // without a promise to invoke the callback at some point in the future,
       // so the request is failed.
-      SdchManager::SdchErrorRecovery(SdchManager::DICTIONARY_FETCH_READ_FAILED);
+      SdchManager::SdchErrorRecovery(SDCH_DICTIONARY_FETCH_READ_FAILED);
+      current_request_->net_log().AddEvent(
+          NetLog::TYPE_SDCH_DICTIONARY_ERROR,
+          base::Bind(&NetLogSdchDictionaryFetchProblemCallback,
+                     SDCH_DICTIONARY_FETCH_READ_FAILED, current_request_->url(),
+                     true));
       DLOG(FATAL)
           << "URLRequest::Read() returned false without IO pending or error!";
       return ERR_FAILED;
@@ -228,8 +234,10 @@
   DCHECK(CalledOnValidThread());
 
   // If the dictionary was successfully fetched, add it to the manager.
-  if (rv == OK)
-    dictionary_fetched_callback_.Run(dictionary_, current_request_->url());
+  if (rv == OK) {
+    dictionary_fetched_callback_.Run(dictionary_, current_request_->url(),
+                                     current_request_->net_log());
+  }
 
   current_request_.reset();
   buffer_ = NULL;
diff --git a/net/url_request/sdch_dictionary_fetcher.h b/net/url_request/sdch_dictionary_fetcher.h
index 5b6f269..79d8778 100644
--- a/net/url_request/sdch_dictionary_fetcher.h
+++ b/net/url_request/sdch_dictionary_fetcher.h
@@ -36,7 +36,8 @@
                                          public base::NonThreadSafe {
  public:
   typedef base::Callback<void(const std::string& dictionary_text,
-                              const GURL& dictionary_url)>
+                              const GURL& dictionary_url,
+                              const BoundNetLog& net_log)>
       OnDictionaryFetchedCallback;
 
   // The consumer must guarantee that |*context| outlives this object.
diff --git a/net/url_request/sdch_dictionary_fetcher_unittest.cc b/net/url_request/sdch_dictionary_fetcher_unittest.cc
index 0febd7e..ae76cbc 100644
--- a/net/url_request/sdch_dictionary_fetcher_unittest.cc
+++ b/net/url_request/sdch_dictionary_fetcher_unittest.cc
@@ -99,7 +99,8 @@
   }
 
   void OnDictionaryFetched(const std::string& dictionary_text,
-                           const GURL& dictionary_url) {
+                           const GURL& dictionary_url,
+                           const BoundNetLog& net_log) {
     dictionary_additions.push_back(
         DictionaryAdditions(dictionary_text, dictionary_url));
   }
diff --git a/net/url_request/test_url_fetcher_factory.cc b/net/url_request/test_url_fetcher_factory.cc
index af76576..357dfeb 100644
--- a/net/url_request/test_url_fetcher_factory.cc
+++ b/net/url_request/test_url_fetcher_factory.cc
@@ -48,6 +48,7 @@
       fake_response_destination_(STRING),
       fake_was_fetched_via_proxy_(false),
       fake_max_retries_(0) {
+  CHECK(original_url_.is_valid());
 }
 
 TestURLFetcher::~TestURLFetcher() {
diff --git a/net/url_request/url_fetcher.cc b/net/url_request/url_fetcher.cc
index 96a2510..ddad12d 100644
--- a/net/url_request/url_fetcher.cc
+++ b/net/url_request/url_fetcher.cc
@@ -36,11 +36,6 @@
 }
 
 // static
-void net::URLFetcher::SetEnableInterceptionForTests(bool enabled) {
-  URLFetcherImpl::SetEnableInterceptionForTests(enabled);
-}
-
-// static
 void net::URLFetcher::SetIgnoreCertificateRequests(bool ignored) {
   URLFetcherImpl::SetIgnoreCertificateRequests(ignored);
 }
diff --git a/net/url_request/url_fetcher.h b/net/url_request/url_fetcher.h
index 1b379c4..5dcaedd 100644
--- a/net/url_request/url_fetcher.h
+++ b/net/url_request/url_fetcher.h
@@ -119,11 +119,6 @@
   // thread though, even though the task won't ever run.
   static void CancelAll();
 
-  // Normally interception is disabled for URLFetcher, but you can use this
-  // to enable it for tests. Also see ScopedURLFetcherFactory for another way
-  // of testing code that uses an URLFetcher.
-  static void SetEnableInterceptionForTests(bool enabled);
-
   // Normally, URLFetcher will abort loads that request SSL client certificate
   // authentication, but this method may be used to cause URLFetchers to ignore
   // requests for client certificates and continue anonymously. Because such
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc
index 5ea3921..aae47d9 100644
--- a/net/url_request/url_fetcher_core.cc
+++ b/net/url_request/url_fetcher_core.cc
@@ -34,7 +34,6 @@
 
 const int kBufferSize = 4096;
 const int kUploadProgressTimerInterval = 100;
-bool g_interception_enabled = false;
 bool g_ignore_certificate_requests = false;
 
 void EmptyCompletionCallback(int result) {}
@@ -470,10 +469,6 @@
   return g_registry.Get().size();
 }
 
-void URLFetcherCore::SetEnableInterceptionForTests(bool enabled) {
-  g_interception_enabled = enabled;
-}
-
 void URLFetcherCore::SetIgnoreCertificateRequests(bool ignored) {
   g_ignore_certificate_requests = ignored;
 }
@@ -514,8 +509,6 @@
       original_url_, DEFAULT_PRIORITY, this, NULL);
   request_->set_stack_trace(stack_trace_);
   int flags = request_->load_flags() | load_flags_;
-  if (!g_interception_enabled)
-    flags = flags | LOAD_DISABLE_INTERCEPT;
 
   if (is_chunked_upload_)
     request_->EnableChunkedUpload();
diff --git a/net/url_request/url_fetcher_impl.cc b/net/url_request/url_fetcher_impl.cc
index fc44551..179adfb 100644
--- a/net/url_request/url_fetcher_impl.cc
+++ b/net/url_request/url_fetcher_impl.cc
@@ -193,11 +193,6 @@
 }
 
 // static
-void URLFetcherImpl::SetEnableInterceptionForTests(bool enabled) {
-  URLFetcherCore::SetEnableInterceptionForTests(enabled);
-}
-
-// static
 void URLFetcherImpl::SetIgnoreCertificateRequests(bool ignored) {
   URLFetcherCore::SetIgnoreCertificateRequests(ignored);
 }
diff --git a/net/url_request/url_fetcher_impl.h b/net/url_request/url_fetcher_impl.h
index 29c8bd5..f0a57af 100644
--- a/net/url_request/url_fetcher_impl.h
+++ b/net/url_request/url_fetcher_impl.h
@@ -90,7 +90,6 @@
 
   static void CancelAll();
 
-  static void SetEnableInterceptionForTests(bool enabled);
   static void SetIgnoreCertificateRequests(bool ignored);
 
   // TODO(akalin): Make these private again once URLFetcher::Create()
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
index 613d9bb..a2ce07e 100644
--- a/net/url_request/url_request.cc
+++ b/net/url_request/url_request.cc
@@ -142,31 +142,6 @@
 
 }  // namespace
 
-void URLRequest::Deprecated::RegisterRequestInterceptor(
-    Interceptor* interceptor) {
-  URLRequest::RegisterRequestInterceptor(interceptor);
-}
-
-void URLRequest::Deprecated::UnregisterRequestInterceptor(
-    Interceptor* interceptor) {
-  URLRequest::UnregisterRequestInterceptor(interceptor);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// URLRequest::Interceptor
-
-URLRequestJob* URLRequest::Interceptor::MaybeInterceptRedirect(
-    URLRequest* request,
-    NetworkDelegate* network_delegate,
-    const GURL& location) {
-  return NULL;
-}
-
-URLRequestJob* URLRequest::Interceptor::MaybeInterceptResponse(
-    URLRequest* request, NetworkDelegate* network_delegate) {
-  return NULL;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // URLRequest::Delegate
 
@@ -624,17 +599,6 @@
   net_log_.BeginEvent(NetLog::TYPE_REQUEST_ALIVE);
 }
 
-// static
-void URLRequest::RegisterRequestInterceptor(Interceptor* interceptor) {
-  URLRequestJobManager::GetInstance()->RegisterRequestInterceptor(interceptor);
-}
-
-// static
-void URLRequest::UnregisterRequestInterceptor(Interceptor* interceptor) {
-  URLRequestJobManager::GetInstance()->UnregisterRequestInterceptor(
-      interceptor);
-}
-
 void URLRequest::BeforeRequestComplete(int error) {
   DCHECK(!job_.get());
   DCHECK_NE(ERR_IO_PENDING, error);
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h
index 3db6c68..6117419 100644
--- a/net/url_request/url_request.h
+++ b/net/url_request/url_request.h
@@ -40,12 +40,6 @@
 }  // namespace debug
 }  // namespace base
 
-// Temporary layering violation to allow existing users of a deprecated
-// interface.
-namespace content {
-class AppCacheInterceptor;
-}
-
 namespace net {
 
 class ChunkedUploadDataStream;
@@ -120,58 +114,6 @@
     UPDATE_FIRST_PARTY_URL_ON_REDIRECT,
   };
 
-  // This class handles network interception.  Use with
-  // (Un)RegisterRequestInterceptor.
-  class NET_EXPORT Interceptor {
-   public:
-    virtual ~Interceptor() {}
-
-    // Called for every request made.  Should return a new job to handle the
-    // request if it should be intercepted, or NULL to allow the request to
-    // be handled in the normal manner.
-    virtual URLRequestJob* MaybeIntercept(
-        URLRequest* request, NetworkDelegate* network_delegate) = 0;
-
-    // Called after having received a redirect response, but prior to the
-    // the request delegate being informed of the redirect. Can return a new
-    // job to replace the existing job if it should be intercepted, or NULL
-    // to allow the normal handling to continue. If a new job is provided,
-    // the delegate never sees the original redirect response, instead the
-    // response produced by the intercept job will be returned.
-    virtual URLRequestJob* MaybeInterceptRedirect(
-        URLRequest* request,
-        NetworkDelegate* network_delegate,
-        const GURL& location);
-
-    // Called after having received a final response, but prior to the
-    // the request delegate being informed of the response. This is also
-    // called when there is no server response at all to allow interception
-    // on dns or network errors. Can return a new job to replace the existing
-    // job if it should be intercepted, or NULL to allow the normal handling to
-    // continue. If a new job is provided, the delegate never sees the original
-    // response, instead the response produced by the intercept job will be
-    // returned.
-    virtual URLRequestJob* MaybeInterceptResponse(
-        URLRequest* request, NetworkDelegate* network_delegate);
-  };
-
-  // Deprecated interfaces in net::URLRequest. They have been moved to
-  // URLRequest's private section to prevent new uses. Existing uses are
-  // explicitly friended here and should be removed over time.
-  class NET_EXPORT Deprecated {
-   private:
-    // TODO(willchan): Kill off these friend declarations.
-    friend class TestInterceptor;
-    friend class content::AppCacheInterceptor;
-
-    // TODO(pauljensen): Remove this when AppCacheInterceptor is a
-    // ProtocolHandler, see crbug.com/161547.
-    static void RegisterRequestInterceptor(Interceptor* interceptor);
-    static void UnregisterRequestInterceptor(Interceptor* interceptor);
-
-    DISALLOW_IMPLICIT_CONSTRUCTORS(Deprecated);
-  };
-
   // The delegate's methods are called from the message loop of the thread
   // on which the request's Start() method is called. See above for the
   // ordering of callbacks.
@@ -717,10 +659,6 @@
              CookieStore* cookie_store,
              NetworkDelegate* network_delegate);
 
-  // Registers or unregisters a network interception class.
-  static void RegisterRequestInterceptor(Interceptor* interceptor);
-  static void UnregisterRequestInterceptor(Interceptor* interceptor);
-
   // Resumes or blocks a request paused by the NetworkDelegate::OnBeforeRequest
   // handler. If |blocked| is true, the request is blocked and an error page is
   // returned indicating so. This should only be called after Start is called
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc
index 04c190c..41420d5 100644
--- a/net/url_request/url_request_context_builder.cc
+++ b/net/url_request/url_request_context_builder.cc
@@ -214,7 +214,8 @@
       ftp_enabled_(false),
 #endif
       http_cache_enabled_(true),
-      throttling_enabled_(false) {
+      throttling_enabled_(false),
+      channel_id_enabled_(true) {
 }
 
 URLRequestContextBuilder::~URLRequestContextBuilder() {}
@@ -296,12 +297,14 @@
   storage->set_http_auth_handler_factory(http_auth_handler_registry_factory);
   storage->set_cookie_store(new CookieMonster(NULL, NULL));
 
-  // TODO(mmenke):  This always creates a file thread, even when it ends up
-  // not being used.  Consider lazily creating the thread.
-  storage->set_channel_id_service(
-      new ChannelIDService(
-          new DefaultChannelIDStore(NULL),
-          context->GetFileThread()->message_loop_proxy()));
+  if (channel_id_enabled_) {
+    // TODO(mmenke):  This always creates a file thread, even when it ends up
+    // not being used.  Consider lazily creating the thread.
+    storage->set_channel_id_service(
+        new ChannelIDService(
+            new DefaultChannelIDStore(NULL),
+            context->GetFileThread()->message_loop_proxy()));
+  }
 
   storage->set_transport_security_state(new net::TransportSecurityState());
   if (!transport_security_persister_path_.empty()) {
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h
index a7d9d7b..f26552a 100644
--- a/net/url_request/url_request_context_builder.h
+++ b/net/url_request/url_request_context_builder.h
@@ -174,6 +174,10 @@
     throttling_enabled_ = throttling_enabled;
   }
 
+  void set_channel_id_enabled(bool enable) {
+    channel_id_enabled_ = enable;
+  }
+
   URLRequestContext* Build();
 
  private:
@@ -200,6 +204,7 @@
 #endif
   bool http_cache_enabled_;
   bool throttling_enabled_;
+  bool channel_id_enabled_;
 
   HttpCacheParams http_cache_params_;
   HttpNetworkSessionParams http_network_session_params_;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 4261b92..33a5088 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -24,6 +24,7 @@
 #include "net/base/net_util.h"
 #include "net/base/network_delegate.h"
 #include "net/base/sdch_manager.h"
+#include "net/base/sdch_net_log_params.h"
 #include "net/cert/cert_status_flags.h"
 #include "net/cookies/cookie_store.h"
 #include "net/http/http_content_disposition.h"
@@ -70,6 +71,7 @@
   int GetResponseCode() const override;
   const URLRequestContext* GetURLRequestContext() const override;
   void RecordPacketStats(StatisticSelector statistic) const override;
+  const BoundNetLog& GetNetLog() const override;
 
   // Method to allow us to reset filter context for a response that should have
   // been SDCH encoded when there is an update due to an explicit HTTP header.
@@ -78,6 +80,10 @@
  private:
   URLRequestHttpJob* job_;
 
+  // URLRequestHttpJob may be detached from URLRequest, but we still need to
+  // return something.
+  BoundNetLog dummy_log_;
+
   DISALLOW_COPY_AND_ASSIGN(HttpFilterContext);
 };
 
@@ -147,6 +153,10 @@
   job_->RecordPacketStats(statistic);
 }
 
+const BoundNetLog& URLRequestHttpJob::HttpFilterContext::GetNetLog() const {
+  return job_->request() ? job_->request()->net_log() : dummy_log_;
+}
+
 // TODO(darin): make sure the port blocking code is not lost
 // static
 URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request,
@@ -321,21 +331,42 @@
   ProcessPublicKeyPinsHeader();
 
   SdchManager* sdch_manager(request()->context()->sdch_manager());
-  if (sdch_manager && sdch_manager->IsInSupportedDomain(request_->url())) {
-    const std::string name = "Get-Dictionary";
-    std::string url_text;
-    void* iter = NULL;
-    // TODO(jar): We need to not fetch dictionaries the first time they are
-    // seen, but rather wait until we can justify their usefulness.
-    // For now, we will only fetch the first dictionary, which will at least
-    // require multiple suggestions before we get additional ones for this site.
-    // Eventually we should wait until a dictionary is requested several times
-    // before we even download it (so that we don't waste memory or bandwidth).
-    if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) {
-      // Resolve suggested URL relative to request url.
-      GURL sdch_dictionary_url = request_->url().Resolve(url_text);
-      if (sdch_dictionary_url.is_valid()) {
-        sdch_manager->OnGetDictionary(request_->url(), sdch_dictionary_url);
+  if (sdch_manager) {
+    SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url());
+    if (rv != SDCH_OK) {
+      // If SDCH is just disabled, it is not a real error.
+      if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) {
+        SdchManager::SdchErrorRecovery(rv);
+        request()->net_log().AddEvent(
+            NetLog::TYPE_SDCH_DECODING_ERROR,
+            base::Bind(&NetLogSdchResourceProblemCallback, rv));
+      }
+    } else {
+      const std::string name = "Get-Dictionary";
+      std::string url_text;
+      void* iter = NULL;
+      // TODO(jar): We need to not fetch dictionaries the first time they are
+      // seen, but rather wait until we can justify their usefulness.
+      // For now, we will only fetch the first dictionary, which will at least
+      // require multiple suggestions before we get additional ones for this
+      // site. Eventually we should wait until a dictionary is requested
+      // several times
+      // before we even download it (so that we don't waste memory or
+      // bandwidth).
+      if (GetResponseHeaders()->EnumerateHeader(&iter, name, &url_text)) {
+        // Resolve suggested URL relative to request url.
+        GURL sdch_dictionary_url = request_->url().Resolve(url_text);
+        if (sdch_dictionary_url.is_valid()) {
+          rv = sdch_manager->OnGetDictionary(request_->url(),
+                                             sdch_dictionary_url);
+          if (rv != SDCH_OK) {
+            SdchManager::SdchErrorRecovery(rv);
+            request_->net_log().AddEvent(
+                NetLog::TYPE_SDCH_DICTIONARY_ERROR,
+                base::Bind(&NetLogSdchDictionaryFetchProblemCallback, rv,
+                           sdch_dictionary_url, false));
+          }
+        }
       }
     }
   }
@@ -483,13 +514,24 @@
   // simple_data_source.
   if (!request_info_.extra_headers.HasHeader(
       HttpRequestHeaders::kAcceptEncoding)) {
-    bool advertise_sdch = sdch_manager &&
-        // We don't support SDCH responses to POST as there is a possibility
-        // of having SDCH encoded responses returned (e.g. by the cache)
-        // which we cannot decode, and in those situations, we will need
-        // to retransmit the request without SDCH, which is illegal for a POST.
-        request()->method() != "POST" &&
-        sdch_manager->IsInSupportedDomain(request_->url());
+    // We don't support SDCH responses to POST as there is a possibility
+    // of having SDCH encoded responses returned (e.g. by the cache)
+    // which we cannot decode, and in those situations, we will need
+    // to retransmit the request without SDCH, which is illegal for a POST.
+    bool advertise_sdch = sdch_manager != NULL && request()->method() != "POST";
+    if (advertise_sdch) {
+      SdchProblemCode rv = sdch_manager->IsInSupportedDomain(request()->url());
+      if (rv != SDCH_OK) {
+        advertise_sdch = false;
+        // If SDCH is just disabled, it is not a real error.
+        if (rv != SDCH_DISABLED && rv != SDCH_SECURE_SCHEME_NOT_SUPPORTED) {
+          SdchManager::SdchErrorRecovery(rv);
+          request()->net_log().AddEvent(
+              NetLog::TYPE_SDCH_DECODING_ERROR,
+              base::Bind(&NetLogSdchResourceProblemCallback, rv));
+        }
+      }
+    }
     std::string avail_dictionaries;
     if (advertise_sdch) {
       sdch_manager->GetAvailDictionaryList(request_->url(),
diff --git a/net/url_request/url_request_job_manager.cc b/net/url_request/url_request_job_manager.cc
index 6fcff22..a1540fa 100644
--- a/net/url_request/url_request_job_manager.cc
+++ b/net/url_request/url_request_job_manager.cc
@@ -68,18 +68,6 @@
 
   // See if the request should be intercepted.
   //
-
-  // TODO(pauljensen): Remove this when AppCacheInterceptor is a
-  // ProtocolHandler, see crbug.com/161547.
-  if (!(request->load_flags() & LOAD_DISABLE_INTERCEPT)) {
-    InterceptorList::const_iterator i;
-    for (i = interceptors_.begin(); i != interceptors_.end(); ++i) {
-      URLRequestJob* job = (*i)->MaybeIntercept(request, network_delegate);
-      if (job)
-        return job;
-    }
-  }
-
   URLRequestJob* job = job_factory->MaybeCreateJobWithProtocolHandler(
       scheme, request, network_delegate);
   if (job)
@@ -108,7 +96,6 @@
     const GURL& location) const {
   DCHECK(IsAllowedThread());
   if (!request->url().is_valid() ||
-      request->load_flags() & LOAD_DISABLE_INTERCEPT ||
       request->status().status() == URLRequestStatus::CANCELED) {
     return NULL;
   }
@@ -120,15 +107,6 @@
   if (!job_factory->IsHandledProtocol(scheme))
     return NULL;
 
-  InterceptorList::const_iterator i;
-  for (i = interceptors_.begin(); i != interceptors_.end(); ++i) {
-    URLRequestJob* job = (*i)->MaybeInterceptRedirect(request,
-                                                      network_delegate,
-                                                      location);
-    if (job)
-      return job;
-  }
-
   URLRequestJob* job =
       request->context()->job_factory()->MaybeInterceptRedirect(
           request, network_delegate, location);
@@ -142,7 +120,6 @@
     URLRequest* request, NetworkDelegate* network_delegate) const {
   DCHECK(IsAllowedThread());
   if (!request->url().is_valid() ||
-      request->load_flags() & LOAD_DISABLE_INTERCEPT ||
       request->status().status() == URLRequestStatus::CANCELED) {
     return NULL;
   }
@@ -154,14 +131,6 @@
   if (!job_factory->IsHandledProtocol(scheme))
     return NULL;
 
-  InterceptorList::const_iterator i;
-  for (i = interceptors_.begin(); i != interceptors_.end(); ++i) {
-    URLRequestJob* job = (*i)->MaybeInterceptResponse(request,
-                                                      network_delegate);
-    if (job)
-      return job;
-  }
-
   URLRequestJob* job =
       request->context()->job_factory()->MaybeInterceptResponse(
           request, network_delegate);
@@ -181,29 +150,6 @@
   return false;
 }
 
-void URLRequestJobManager::RegisterRequestInterceptor(
-    URLRequest::Interceptor* interceptor) {
-  DCHECK(IsAllowedThread());
-
-  base::AutoLock locked(lock_);
-
-  DCHECK(std::find(interceptors_.begin(), interceptors_.end(), interceptor) ==
-         interceptors_.end());
-  interceptors_.push_back(interceptor);
-}
-
-void URLRequestJobManager::UnregisterRequestInterceptor(
-    URLRequest::Interceptor* interceptor) {
-  DCHECK(IsAllowedThread());
-
-  base::AutoLock locked(lock_);
-
-  InterceptorList::iterator i =
-      std::find(interceptors_.begin(), interceptors_.end(), interceptor);
-  DCHECK(i != interceptors_.end());
-  interceptors_.erase(i);
-}
-
 URLRequestJobManager::URLRequestJobManager()
     : allowed_thread_(0),
       allowed_thread_initialized_(false) {
diff --git a/net/url_request/url_request_job_manager.h b/net/url_request/url_request_job_manager.h
index 9877bed..ca67e56 100644
--- a/net/url_request/url_request_job_manager.h
+++ b/net/url_request/url_request_job_manager.h
@@ -51,12 +51,7 @@
   // Returns true if the manager has a built-in handler for |scheme|.
   static bool SupportsScheme(const std::string& scheme);
 
-  // Register/unregister a request interceptor.
-  void RegisterRequestInterceptor(URLRequest::Interceptor* interceptor);
-  void UnregisterRequestInterceptor(URLRequest::Interceptor* interceptor);
-
  private:
-  typedef std::vector<URLRequest::Interceptor*> InterceptorList;
   friend struct DefaultSingletonTraits<URLRequestJobManager>;
 
   URLRequestJobManager();
@@ -92,7 +87,6 @@
 #endif
 
   mutable base::Lock lock_;
-  InterceptorList interceptors_;
 
   DISALLOW_COPY_AND_ASSIGN(URLRequestJobManager);
 };
diff --git a/net/url_request/url_request_simple_job.cc b/net/url_request/url_request_simple_job.cc
index b855932..55a0f88 100644
--- a/net/url_request/url_request_simple_job.cc
+++ b/net/url_request/url_request_simple_job.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/compiler_specific.h"
+#include "base/memory/ref_counted_memory.h"
 #include "base/message_loop/message_loop.h"
 #include "base/profiler/scoped_tracker.h"
 #include "net/base/io_buffer.h"
@@ -50,12 +51,31 @@
   int remaining = byte_range_.last_byte_position() - data_offset_ + 1;
   if (buf_size > remaining)
     buf_size = remaining;
-  memcpy(buf->data(), data_.data() + data_offset_, buf_size);
+  memcpy(buf->data(), data_->front() + data_offset_, buf_size);
   data_offset_ += buf_size;
   *bytes_read = buf_size;
   return true;
 }
 
+int URLRequestSimpleJob::GetData(std::string* mime_type,
+                                 std::string* charset,
+                                 std::string* data,
+                                 const CompletionCallback& callback) const {
+  NOTREACHED();
+  return ERR_UNEXPECTED;
+}
+
+int URLRequestSimpleJob::GetRefCountedData(
+    std::string* mime_type,
+    std::string* charset,
+    scoped_refptr<base::RefCountedMemory>* data,
+    const CompletionCallback& callback) const {
+  scoped_refptr<base::RefCountedString> str_data(new base::RefCountedString());
+  int result = GetData(mime_type, charset, &str_data->data(), callback);
+  *data = str_data;
+  return result;
+}
+
 void URLRequestSimpleJob::StartAsync() {
   if (!request_)
     return;
@@ -82,11 +102,10 @@
         FROM_HERE_WITH_EXPLICIT_FUNCTION(
             "422489 URLRequestSimpleJob::StartAsync 2"));
 
-    result = GetData(&mime_type_,
-                     &charset_,
-                     &data_,
-                     base::Bind(&URLRequestSimpleJob::OnGetDataCompleted,
-                                weak_factory_.GetWeakPtr()));
+    result =
+        GetRefCountedData(&mime_type_, &charset_, &data_,
+                          base::Bind(&URLRequestSimpleJob::OnGetDataCompleted,
+                                     weak_factory_.GetWeakPtr()));
   }
 
   if (result != ERR_IO_PENDING) {
@@ -107,7 +126,7 @@
 
   if (result == OK) {
     // Notify that the headers are complete
-    if (!byte_range_.ComputeBounds(data_.size())) {
+    if (!byte_range_.ComputeBounds(data_->size())) {
       NotifyDone(URLRequestStatus(URLRequestStatus::FAILED,
                  ERR_REQUEST_RANGE_NOT_SATISFIABLE));
       return;
diff --git a/net/url_request/url_request_simple_job.h b/net/url_request/url_request_simple_job.h
index 85d8f7e..99b6cb6 100644
--- a/net/url_request/url_request_simple_job.h
+++ b/net/url_request/url_request_simple_job.h
@@ -7,11 +7,17 @@
 
 #include <string>
 
+#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/strings/string_piece.h"
 #include "net/base/completion_callback.h"
 #include "net/base/net_export.h"
 #include "net/url_request/url_range_request_job.h"
 
+namespace base {
+class RefCountedMemory;
+}
+
 namespace net {
 
 class URLRequest;
@@ -28,7 +34,8 @@
  protected:
   ~URLRequestSimpleJob() override;
 
-  // Subclasses must override the way response data is determined.
+  // Subclasses must override either GetData or GetRefCountedData to define the
+  // way response data is determined.
   // The return value should be:
   //  - OK if data is obtained;
   //  - ERR_IO_PENDING if async processing is needed to finish obtaining data.
@@ -41,9 +48,15 @@
   virtual int GetData(std::string* mime_type,
                       std::string* charset,
                       std::string* data,
-                      const CompletionCallback& callback) const = 0;
+                      const CompletionCallback& callback) const;
 
- protected:
+  // Similar to GetData(), except |*data| can share ownership of the bytes
+  // instead of copying them into a std::string.
+  virtual int GetRefCountedData(std::string* mime_type,
+                                std::string* charset,
+                                scoped_refptr<base::RefCountedMemory>* data,
+                                const CompletionCallback& callback) const;
+
   void StartAsync();
 
  private:
@@ -52,7 +65,7 @@
   HttpByteRange byte_range_;
   std::string mime_type_;
   std::string charset_;
-  std::string data_;
+  scoped_refptr<base::RefCountedMemory> data_;
   int data_offset_;
   base::WeakPtrFactory<URLRequestSimpleJob> weak_factory_;
 };
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 2aeecc6..1d777dc 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -1158,445 +1158,6 @@
   ~CancelThenRestartTestJob() override {}
 };
 
-// An Interceptor for use with interceptor tests
-class TestInterceptor : URLRequest::Interceptor {
- public:
-  TestInterceptor()
-      : intercept_main_request_(false), restart_main_request_(false),
-        cancel_main_request_(false), cancel_then_restart_main_request_(false),
-        simulate_main_network_error_(false),
-        intercept_redirect_(false), cancel_redirect_request_(false),
-        intercept_final_response_(false), cancel_final_request_(false),
-        did_intercept_main_(false), did_restart_main_(false),
-        did_cancel_main_(false), did_cancel_then_restart_main_(false),
-        did_simulate_error_main_(false),
-        did_intercept_redirect_(false), did_cancel_redirect_(false),
-        did_intercept_final_(false), did_cancel_final_(false) {
-    URLRequest::Deprecated::RegisterRequestInterceptor(this);
-  }
-
-  ~TestInterceptor() override {
-    URLRequest::Deprecated::UnregisterRequestInterceptor(this);
-  }
-
-  URLRequestJob* MaybeIntercept(URLRequest* request,
-                                NetworkDelegate* network_delegate) override {
-    if (restart_main_request_) {
-      restart_main_request_ = false;
-      did_restart_main_ = true;
-      return new RestartTestJob(request, network_delegate);
-    }
-    if (cancel_main_request_) {
-      cancel_main_request_ = false;
-      did_cancel_main_ = true;
-      return new CancelTestJob(request, network_delegate);
-    }
-    if (cancel_then_restart_main_request_) {
-      cancel_then_restart_main_request_ = false;
-      did_cancel_then_restart_main_ = true;
-      return new CancelThenRestartTestJob(request, network_delegate);
-    }
-    if (simulate_main_network_error_) {
-      simulate_main_network_error_ = false;
-      did_simulate_error_main_ = true;
-      // will error since the requeted url is not one of its canned urls
-      return new URLRequestTestJob(request, network_delegate, true);
-    }
-    if (!intercept_main_request_)
-      return NULL;
-    intercept_main_request_ = false;
-    did_intercept_main_ = true;
-    URLRequestTestJob* job =  new URLRequestTestJob(request,
-                                                    network_delegate,
-                                                    main_headers_,
-                                                    main_data_,
-                                                    true);
-    job->set_load_timing_info(main_request_load_timing_info_);
-    return job;
-  }
-
-  URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
-                                        NetworkDelegate* network_delegate,
-                                        const GURL& location) override {
-    if (cancel_redirect_request_) {
-      cancel_redirect_request_ = false;
-      did_cancel_redirect_ = true;
-      return new CancelTestJob(request, network_delegate);
-    }
-    if (!intercept_redirect_)
-      return NULL;
-    intercept_redirect_ = false;
-    did_intercept_redirect_ = true;
-    return new URLRequestTestJob(request,
-                                 network_delegate,
-                                 redirect_headers_,
-                                 redirect_data_,
-                                 true);
-  }
-
-  URLRequestJob* MaybeInterceptResponse(
-      URLRequest* request,
-      NetworkDelegate* network_delegate) override {
-    if (cancel_final_request_) {
-      cancel_final_request_ = false;
-      did_cancel_final_ = true;
-      return new CancelTestJob(request, network_delegate);
-    }
-    if (!intercept_final_response_)
-      return NULL;
-    intercept_final_response_ = false;
-    did_intercept_final_ = true;
-    return new URLRequestTestJob(request,
-                                 network_delegate,
-                                 final_headers_,
-                                 final_data_,
-                                 true);
-  }
-
-  // Whether to intercept the main request, and if so the response to return and
-  // the LoadTimingInfo to use.
-  bool intercept_main_request_;
-  std::string main_headers_;
-  std::string main_data_;
-  LoadTimingInfo main_request_load_timing_info_;
-
-  // Other actions we take at MaybeIntercept time
-  bool restart_main_request_;
-  bool cancel_main_request_;
-  bool cancel_then_restart_main_request_;
-  bool simulate_main_network_error_;
-
-  // Whether to intercept redirects, and if so the response to return.
-  bool intercept_redirect_;
-  std::string redirect_headers_;
-  std::string redirect_data_;
-
-  // Other actions we can take at MaybeInterceptRedirect time
-  bool cancel_redirect_request_;
-
-  // Whether to intercept final response, and if so the response to return.
-  bool intercept_final_response_;
-  std::string final_headers_;
-  std::string final_data_;
-
-  // Other actions we can take at MaybeInterceptResponse time
-  bool cancel_final_request_;
-
-  // If we did something or not
-  bool did_intercept_main_;
-  bool did_restart_main_;
-  bool did_cancel_main_;
-  bool did_cancel_then_restart_main_;
-  bool did_simulate_error_main_;
-  bool did_intercept_redirect_;
-  bool did_cancel_redirect_;
-  bool did_intercept_final_;
-  bool did_cancel_final_;
-
-  // Static getters for canned response header and data strings
-
-  static std::string ok_data() {
-    return URLRequestTestJob::test_data_1();
-  }
-
-  static std::string ok_headers() {
-    return URLRequestTestJob::test_headers();
-  }
-
-  static std::string redirect_data() {
-    return std::string();
-  }
-
-  static std::string redirect_headers() {
-    return URLRequestTestJob::test_redirect_headers();
-  }
-
-  static std::string error_data() {
-    return std::string("ohhh nooooo mr. bill!");
-  }
-
-  static std::string error_headers() {
-    return URLRequestTestJob::test_error_headers();
-  }
-};
-
-TEST_F(URLRequestTest, Intercept) {
-  TestInterceptor interceptor;
-
-  // intercept the main request and respond with a simple response
-  interceptor.intercept_main_request_ = true;
-  interceptor.main_headers_ = TestInterceptor::ok_headers();
-  interceptor.main_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data();
-  base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data();
-  base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data();
-  req->SetUserData(NULL, user_data0);
-  req->SetUserData(&user_data1, user_data1);
-  req->SetUserData(&user_data2, user_data2);
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Make sure we can retrieve our specific user data
-  EXPECT_EQ(user_data0, req->GetUserData(NULL));
-  EXPECT_EQ(user_data1, req->GetUserData(&user_data1));
-  EXPECT_EQ(user_data2, req->GetUserData(&user_data2));
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_intercept_main_);
-
-  // Check we got one good response
-  EXPECT_TRUE(req->status().is_success());
-  EXPECT_EQ(200, req->response_headers()->response_code());
-  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
-  EXPECT_EQ(1, d.response_started_count());
-  EXPECT_EQ(0, d.received_redirect_count());
-}
-
-TEST_F(URLRequestTest, InterceptRedirect) {
-  TestInterceptor interceptor;
-
-  // intercept the main request and respond with a redirect
-  interceptor.intercept_main_request_ = true;
-  interceptor.main_headers_ = TestInterceptor::redirect_headers();
-  interceptor.main_data_ = TestInterceptor::redirect_data();
-
-  // intercept that redirect and respond a final OK response
-  interceptor.intercept_redirect_ = true;
-  interceptor.redirect_headers_ =  TestInterceptor::ok_headers();
-  interceptor.redirect_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_intercept_main_);
-  EXPECT_TRUE(interceptor.did_intercept_redirect_);
-
-  // Check we got one good response
-  EXPECT_TRUE(req->status().is_success());
-  if (req->status().is_success()) {
-    EXPECT_EQ(200, req->response_headers()->response_code());
-  }
-  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
-  EXPECT_EQ(1, d.response_started_count());
-  EXPECT_EQ(0, d.received_redirect_count());
-}
-
-TEST_F(URLRequestTest, InterceptServerError) {
-  TestInterceptor interceptor;
-
-  // intercept the main request to generate a server error response
-  interceptor.intercept_main_request_ = true;
-  interceptor.main_headers_ = TestInterceptor::error_headers();
-  interceptor.main_data_ = TestInterceptor::error_data();
-
-  // intercept that error and respond with an OK response
-  interceptor.intercept_final_response_ = true;
-  interceptor.final_headers_ = TestInterceptor::ok_headers();
-  interceptor.final_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_intercept_main_);
-  EXPECT_TRUE(interceptor.did_intercept_final_);
-
-  // Check we got one good response
-  EXPECT_TRUE(req->status().is_success());
-  EXPECT_EQ(200, req->response_headers()->response_code());
-  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
-  EXPECT_EQ(1, d.response_started_count());
-  EXPECT_EQ(0, d.received_redirect_count());
-}
-
-TEST_F(URLRequestTest, InterceptNetworkError) {
-  TestInterceptor interceptor;
-
-  // intercept the main request to simulate a network error
-  interceptor.simulate_main_network_error_ = true;
-
-  // intercept that error and respond with an OK response
-  interceptor.intercept_final_response_ = true;
-  interceptor.final_headers_ = TestInterceptor::ok_headers();
-  interceptor.final_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_simulate_error_main_);
-  EXPECT_TRUE(interceptor.did_intercept_final_);
-
-  // Check we received one good response
-  EXPECT_TRUE(req->status().is_success());
-  EXPECT_EQ(200, req->response_headers()->response_code());
-  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
-  EXPECT_EQ(1, d.response_started_count());
-  EXPECT_EQ(0, d.received_redirect_count());
-}
-
-TEST_F(URLRequestTest, InterceptRestartRequired) {
-  TestInterceptor interceptor;
-
-  // restart the main request
-  interceptor.restart_main_request_ = true;
-
-  // then intercept the new main request and respond with an OK response
-  interceptor.intercept_main_request_ = true;
-  interceptor.main_headers_ = TestInterceptor::ok_headers();
-  interceptor.main_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_restart_main_);
-  EXPECT_TRUE(interceptor.did_intercept_main_);
-
-  // Check we received one good response
-  EXPECT_TRUE(req->status().is_success());
-  if (req->status().is_success()) {
-    EXPECT_EQ(200, req->response_headers()->response_code());
-  }
-  EXPECT_EQ(TestInterceptor::ok_data(), d.data_received());
-  EXPECT_EQ(1, d.response_started_count());
-  EXPECT_EQ(0, d.received_redirect_count());
-}
-
-TEST_F(URLRequestTest, InterceptRespectsCancelMain) {
-  TestInterceptor interceptor;
-
-  // intercept the main request and cancel from within the restarted job
-  interceptor.cancel_main_request_ = true;
-
-  // setup to intercept final response and override it with an OK response
-  interceptor.intercept_final_response_ = true;
-  interceptor.final_headers_ = TestInterceptor::ok_headers();
-  interceptor.final_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_cancel_main_);
-  EXPECT_FALSE(interceptor.did_intercept_final_);
-
-  // Check we see a canceled request
-  EXPECT_FALSE(req->status().is_success());
-  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
-}
-
-TEST_F(URLRequestTest, InterceptRespectsCancelRedirect) {
-  TestInterceptor interceptor;
-
-  // intercept the main request and respond with a redirect
-  interceptor.intercept_main_request_ = true;
-  interceptor.main_headers_ = TestInterceptor::redirect_headers();
-  interceptor.main_data_ = TestInterceptor::redirect_data();
-
-  // intercept the redirect and cancel from within that job
-  interceptor.cancel_redirect_request_ = true;
-
-  // setup to intercept final response and override it with an OK response
-  interceptor.intercept_final_response_ = true;
-  interceptor.final_headers_ = TestInterceptor::ok_headers();
-  interceptor.final_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_intercept_main_);
-  EXPECT_TRUE(interceptor.did_cancel_redirect_);
-  EXPECT_FALSE(interceptor.did_intercept_final_);
-
-  // Check we see a canceled request
-  EXPECT_FALSE(req->status().is_success());
-  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
-}
-
-TEST_F(URLRequestTest, InterceptRespectsCancelFinal) {
-  TestInterceptor interceptor;
-
-  // intercept the main request to simulate a network error
-  interceptor.simulate_main_network_error_ = true;
-
-  // setup to intercept final response and cancel from within that job
-  interceptor.cancel_final_request_ = true;
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_simulate_error_main_);
-  EXPECT_TRUE(interceptor.did_cancel_final_);
-
-  // Check we see a canceled request
-  EXPECT_FALSE(req->status().is_success());
-  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
-}
-
-TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) {
-  TestInterceptor interceptor;
-
-  // intercept the main request and cancel then restart from within that job
-  interceptor.cancel_then_restart_main_request_ = true;
-
-  // setup to intercept final response and override it with an OK response
-  interceptor.intercept_final_response_ = true;
-  interceptor.final_headers_ = TestInterceptor::ok_headers();
-  interceptor.final_data_ = TestInterceptor::ok_data();
-
-  TestDelegate d;
-  scoped_ptr<URLRequest> req(default_context_.CreateRequest(
-      GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
-  req->set_method("GET");
-  req->Start();
-  base::RunLoop().Run();
-
-  // Check the interceptor got called as expected
-  EXPECT_TRUE(interceptor.did_cancel_then_restart_main_);
-  EXPECT_FALSE(interceptor.did_intercept_final_);
-
-  // Check we see a canceled request
-  EXPECT_FALSE(req->status().is_success());
-  EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
-}
-
 // An Interceptor for use with interceptor tests.
 class MockURLRequestInterceptor : public URLRequestInterceptor {
  public:
@@ -2144,8 +1705,8 @@
 
   // Set up to intercept the final response and override it with an OK response.
   interceptor()->set_intercept_final_response(true);
-  interceptor()->set_final_headers(TestInterceptor::ok_headers());
-  interceptor()->set_final_data(TestInterceptor::ok_data());
+  interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
+  interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
 
   TestDelegate d;
   scoped_ptr<URLRequest> req(default_context().CreateRequest(