diff --git a/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc b/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc
new file mode 100644
index 0000000..ed77893
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win.cc
@@ -0,0 +1,293 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/dhcp_proxy_script_adapter_fetcher_win.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "base/message_loop_proxy.h"
+#include "base/metrics/histogram.h"
+#include "base/sys_string_conversions.h"
+#include "base/threading/worker_pool.h"
+#include "base/time.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/dhcpcsvc_init_win.h"
+#include "net/proxy/proxy_script_fetcher_impl.h"
+#include "net/url_request/url_request_context.h"
+
+#include <windows.h>
+#include <winsock2.h>
+#include <dhcpcsdk.h>
+#pragma comment(lib, "dhcpcsvc.lib")
+
+namespace {
+
+// Maximum amount of time to wait for response from the Win32 DHCP API.
+const int kTimeoutMs = 2000;
+
+}  // namespace
+
+namespace net {
+
+DhcpProxyScriptAdapterFetcher::DhcpProxyScriptAdapterFetcher(
+    URLRequestContext* url_request_context)
+    : state_(STATE_START),
+      result_(ERR_IO_PENDING),
+      url_request_context_(url_request_context) {
+  DCHECK(url_request_context_);
+}
+
+DhcpProxyScriptAdapterFetcher::~DhcpProxyScriptAdapterFetcher() {
+  Cancel();
+
+  // The WeakPtr we passed to the worker thread may be destroyed on the
+  // worker thread.  This detaches any outstanding WeakPtr state from
+  // the current thread.
+  base::SupportsWeakPtr<DhcpProxyScriptAdapterFetcher>::DetachFromThread();
+}
+
+void DhcpProxyScriptAdapterFetcher::Fetch(
+    const std::string& adapter_name, const CompletionCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  DCHECK_EQ(state_, STATE_START);
+  result_ = ERR_IO_PENDING;
+  pac_script_ = string16();
+  state_ = STATE_WAIT_DHCP;
+  callback_ = callback;
+
+  wait_timer_.Start(FROM_HERE, ImplGetTimeout(),
+                    this, &DhcpProxyScriptAdapterFetcher::OnTimeout);
+  scoped_refptr<DhcpQuery> dhcp_query(ImplCreateDhcpQuery());
+  base::WorkerPool::PostTaskAndReply(
+      FROM_HERE,
+      base::Bind(
+          &DhcpProxyScriptAdapterFetcher::DhcpQuery::GetPacURLForAdapter,
+          dhcp_query.get(),
+          adapter_name),
+      base::Bind(
+          &DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone,
+          AsWeakPtr(),
+          dhcp_query),
+      true);
+}
+
+void DhcpProxyScriptAdapterFetcher::Cancel() {
+  DCHECK(CalledOnValidThread());
+  callback_.Reset();
+  wait_timer_.Stop();
+  script_fetcher_.reset();
+
+  switch (state_) {
+    case STATE_WAIT_DHCP:
+      // Nothing to do here, we let the worker thread run to completion,
+      // the task it posts back when it completes will check the state.
+      break;
+    case STATE_WAIT_URL:
+      break;
+    case STATE_START:
+    case STATE_FINISH:
+    case STATE_CANCEL:
+      break;
+  }
+
+  if (state_ != STATE_FINISH) {
+    result_ = ERR_ABORTED;
+    state_ = STATE_CANCEL;
+  }
+}
+
+bool DhcpProxyScriptAdapterFetcher::DidFinish() const {
+  DCHECK(CalledOnValidThread());
+  return state_ == STATE_FINISH;
+}
+
+int DhcpProxyScriptAdapterFetcher::GetResult() const {
+  DCHECK(CalledOnValidThread());
+  return result_;
+}
+
+string16 DhcpProxyScriptAdapterFetcher::GetPacScript() const {
+  DCHECK(CalledOnValidThread());
+  return pac_script_;
+}
+
+GURL DhcpProxyScriptAdapterFetcher::GetPacURL() const {
+  DCHECK(CalledOnValidThread());
+  return pac_url_;
+}
+
+DhcpProxyScriptAdapterFetcher::DhcpQuery::DhcpQuery() {
+}
+
+DhcpProxyScriptAdapterFetcher::DhcpQuery::~DhcpQuery() {
+}
+
+void DhcpProxyScriptAdapterFetcher::DhcpQuery::GetPacURLForAdapter(
+    const std::string& adapter_name) {
+  url_ = ImplGetPacURLFromDhcp(adapter_name);
+}
+
+const std::string& DhcpProxyScriptAdapterFetcher::DhcpQuery::url() const {
+  return url_;
+}
+
+std::string
+    DhcpProxyScriptAdapterFetcher::DhcpQuery::ImplGetPacURLFromDhcp(
+        const std::string& adapter_name) {
+  return DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name);
+}
+
+void DhcpProxyScriptAdapterFetcher::OnDhcpQueryDone(
+    scoped_refptr<DhcpQuery> dhcp_query) {
+  DCHECK(CalledOnValidThread());
+  // Because we can't cancel the call to the Win32 API, we can expect
+  // it to finish while we are in a few different states.  The expected
+  // one is WAIT_DHCP, but it could be in CANCEL if Cancel() was called,
+  // or FINISH if timeout occurred.
+  DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_CANCEL ||
+         state_ == STATE_FINISH);
+  if (state_ != STATE_WAIT_DHCP)
+    return;
+
+  wait_timer_.Stop();
+
+  pac_url_ = GURL(dhcp_query->url());
+  if (pac_url_.is_empty() || !pac_url_.is_valid()) {
+    result_ = ERR_PAC_NOT_IN_DHCP;
+    TransitionToFinish();
+  } else {
+    state_ = STATE_WAIT_URL;
+    script_fetcher_.reset(ImplCreateScriptFetcher());
+    script_fetcher_->Fetch(
+        pac_url_, &pac_script_,
+        base::Bind(&DhcpProxyScriptAdapterFetcher::OnFetcherDone,
+                   base::Unretained(this)));
+  }
+}
+
+void DhcpProxyScriptAdapterFetcher::OnTimeout() {
+  DCHECK_EQ(state_, STATE_WAIT_DHCP);
+  result_ = ERR_TIMED_OUT;
+  TransitionToFinish();
+}
+
+void DhcpProxyScriptAdapterFetcher::OnFetcherDone(int result) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(state_ == STATE_WAIT_URL || state_ == STATE_CANCEL);
+  if (state_ == STATE_CANCEL)
+    return;
+
+  // At this point, pac_script_ has already been written to.
+  script_fetcher_.reset();
+  result_ = result;
+  TransitionToFinish();
+}
+
+void DhcpProxyScriptAdapterFetcher::TransitionToFinish() {
+  DCHECK(state_ == STATE_WAIT_DHCP || state_ == STATE_WAIT_URL);
+  state_ = STATE_FINISH;
+  CompletionCallback callback = callback_;
+  callback_.Reset();
+
+  // Be careful not to touch any member state after this, as the client
+  // may delete us during this callback.
+  callback.Run(result_);
+}
+
+DhcpProxyScriptAdapterFetcher::State
+    DhcpProxyScriptAdapterFetcher::state() const {
+  return state_;
+}
+
+ProxyScriptFetcher* DhcpProxyScriptAdapterFetcher::ImplCreateScriptFetcher() {
+  return new ProxyScriptFetcherImpl(url_request_context_);
+}
+
+DhcpProxyScriptAdapterFetcher::DhcpQuery*
+    DhcpProxyScriptAdapterFetcher::ImplCreateDhcpQuery() {
+  return new DhcpQuery();
+}
+
+base::TimeDelta DhcpProxyScriptAdapterFetcher::ImplGetTimeout() const {
+  return base::TimeDelta::FromMilliseconds(kTimeoutMs);
+}
+
+// static
+std::string DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(
+    const std::string& adapter_name) {
+  EnsureDhcpcsvcInit();
+
+  std::wstring adapter_name_wide = base::SysMultiByteToWide(adapter_name,
+                                                            CP_ACP);
+
+  DHCPCAPI_PARAMS_ARRAY send_params = { 0, NULL };
+
+  BYTE option_data[] = { 1, 252 };
+  DHCPCAPI_PARAMS wpad_params = { 0 };
+  wpad_params.OptionId = 252;
+  wpad_params.IsVendor = FALSE;  // Surprising, but intentional.
+
+  DHCPCAPI_PARAMS_ARRAY request_params = { 0 };
+  request_params.nParams = 1;
+  request_params.Params = &wpad_params;
+
+  // The maximum message size is typically 4096 bytes on Windows per
+  // http://support.microsoft.com/kb/321592
+  DWORD result_buffer_size = 4096;
+  scoped_ptr_malloc<BYTE> result_buffer;
+  int retry_count = 0;
+  DWORD res = NO_ERROR;
+  do {
+    result_buffer.reset(reinterpret_cast<BYTE*>(malloc(result_buffer_size)));
+
+    // Note that while the DHCPCAPI_REQUEST_SYNCHRONOUS flag seems to indicate
+    // there might be an asynchronous mode, there seems to be (at least in
+    // terms of well-documented use of this API) only a synchronous mode, with
+    // an optional "async notifications later if the option changes" mode.
+    // Even IE9, which we hope to emulate as IE is the most widely deployed
+    // previous implementation of the DHCP aspect of WPAD and the only one
+    // on Windows (Konqueror is the other, on Linux), uses this API with the
+    // synchronous flag.  There seem to be several Microsoft Knowledge Base
+    // articles about calls to this function failing when other flags are used
+    // (e.g. http://support.microsoft.com/kb/885270) so we won't take any
+    // chances on non-standard, poorly documented usage.
+    res = ::DhcpRequestParams(DHCPCAPI_REQUEST_SYNCHRONOUS,
+                              NULL,
+                              const_cast<LPWSTR>(adapter_name_wide.c_str()),
+                              NULL,
+                              send_params, request_params,
+                              result_buffer.get(), &result_buffer_size,
+                              NULL);
+    ++retry_count;
+  } while (res == ERROR_MORE_DATA && retry_count <= 3);
+
+  if (res != NO_ERROR) {
+    LOG(INFO) << "Error fetching PAC URL from DHCP: " << res;
+    UMA_HISTOGRAM_COUNTS("Net.DhcpWpadUnhandledDhcpError", 1);
+  } else if (wpad_params.nBytesData) {
+#ifndef NDEBUG
+    // The result should be ASCII, not wide character.  Some DHCP
+    // servers appear to count the trailing NULL in nBytesData, others
+    // do not.
+    size_t count_without_null =
+        strlen(reinterpret_cast<const char*>(wpad_params.Data));
+    DCHECK(count_without_null == wpad_params.nBytesData ||
+           count_without_null + 1 == wpad_params.nBytesData);
+#endif
+    // Belt and suspenders: First, ensure we NULL-terminate after
+    // nBytesData; this is the inner constructor with nBytesData as a
+    // parameter.  Then, return only up to the first null in case of
+    // embedded NULLs; this is the outer constructor that takes the
+    // result of c_str() on the inner.  If the server is giving us
+    // back a buffer with embedded NULLs, something is broken anyway.
+    return std::string(
+        std::string(reinterpret_cast<const char *>(wpad_params.Data),
+                    wpad_params.nBytesData).c_str());
+  }
+
+  return "";
+}
+
+}  // namespace net
diff --git a/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h b/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h
new file mode 100644
index 0000000..913e271
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win.h
@@ -0,0 +1,176 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_DHCP_PROXY_SCRIPT_ADAPTER_FETCHER_WIN_H_
+#define NET_PROXY_DHCP_PROXY_SCRIPT_ADAPTER_FETCHER_WIN_H_
+
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/string16.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/timer.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "googleurl/src/gurl.h"
+
+namespace net {
+
+class ProxyScriptFetcher;
+class URLRequestContext;
+
+// For a given adapter, this class takes care of first doing a DHCP lookup
+// to get the PAC URL, then if there is one, trying to fetch it.
+class NET_EXPORT_PRIVATE DhcpProxyScriptAdapterFetcher
+    : public base::SupportsWeakPtr<DhcpProxyScriptAdapterFetcher>,
+      NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+  // |url_request_context| must outlive DhcpProxyScriptAdapterFetcher.
+  explicit DhcpProxyScriptAdapterFetcher(
+      URLRequestContext* url_request_context);
+  virtual ~DhcpProxyScriptAdapterFetcher();
+
+  // Starts a fetch.  On completion (but not cancellation), |callback|
+  // will be invoked with the network error indicating success or failure
+  // of fetching a DHCP-configured PAC file on this adapter.
+  //
+  // On completion, results can be obtained via |GetPacScript()|, |GetPacURL()|.
+  //
+  // You may only call Fetch() once on a given instance of
+  // DhcpProxyScriptAdapterFetcher.
+  virtual void Fetch(const std::string& adapter_name,
+                     const net::CompletionCallback& callback);
+
+  // Cancels the fetch on this adapter.
+  virtual void Cancel();
+
+  // Returns true if in the FINISH state (not CANCEL).
+  virtual bool DidFinish() const;
+
+  // Returns the network error indicating the result of the fetch. Will
+  // return IO_PENDING until the fetch is complete or cancelled. This is
+  // the same network error passed to the |callback| provided to |Fetch()|.
+  virtual int GetResult() const;
+
+  // Returns the contents of the PAC file retrieved.  Only valid if
+  // |IsComplete()| is true.  Returns the empty string if |GetResult()|
+  // returns anything other than OK.
+  virtual string16 GetPacScript() const;
+
+  // Returns the PAC URL retrieved from DHCP.  Only guaranteed to be
+  // valid if |IsComplete()| is true.  Returns an empty URL if no URL was
+  // configured in DHCP.  May return a valid URL even if |result()| does
+  // not return OK (this would indicate that we found a URL configured in
+  // DHCP but failed to download it).
+  virtual GURL GetPacURL() const;
+
+  // Returns the PAC URL configured in DHCP for the given |adapter_name|, or
+  // the empty string if none is configured.
+  //
+  // This function executes synchronously due to limitations of the Windows
+  // DHCP client API.
+  static std::string GetPacURLFromDhcp(const std::string& adapter_name);
+
+ protected:
+  // This is the state machine for fetching from a given adapter.
+  //
+  // The state machine goes from START->WAIT_DHCP when it starts
+  // a worker thread to fetch the PAC URL from DHCP.
+  //
+  // In state WAIT_DHCP, if the DHCP query finishes and has no URL, it
+  // moves to state FINISH.  If there is a URL, it starts a
+  // ProxyScriptFetcher to fetch it and moves to state WAIT_URL.
+  //
+  // It goes from WAIT_URL->FINISH when the ProxyScriptFetcher completes.
+  //
+  // In state FINISH, completion is indicated to the outer class, with
+  // the results of the fetch if a PAC script was successfully fetched.
+  //
+  // In state WAIT_DHCP, our timeout occurring can push us to FINISH.
+  //
+  // In any state except FINISH, a call to Cancel() will move to state
+  // CANCEL and cause all outstanding work to be cancelled or its
+  // results ignored when available.
+  enum State {
+    STATE_START,
+    STATE_WAIT_DHCP,
+    STATE_WAIT_URL,
+    STATE_FINISH,
+    STATE_CANCEL,
+  };
+
+  State state() const;
+
+  // This inner class encapsulates work done on a worker pool thread.
+  // By using a separate object, we can keep the main object completely
+  // thread safe and let it be non-refcounted.
+  class NET_EXPORT_PRIVATE DhcpQuery
+      : public base::RefCountedThreadSafe<DhcpQuery> {
+   public:
+    DhcpQuery();
+    virtual ~DhcpQuery();
+
+    // This method should run on a worker pool thread, via PostTaskAndReply.
+    // After it has run, the |url()| method on this object will return the
+    // URL retrieved.
+    void GetPacURLForAdapter(const std::string& adapter_name);
+
+    // Returns the URL retrieved for the given adapter, once the task has run.
+    const std::string& url() const;
+
+   protected:
+    // Virtual method introduced to allow unit testing.
+    virtual std::string ImplGetPacURLFromDhcp(const std::string& adapter_name);
+
+   private:
+    // The URL retrieved for the given adapter.
+    std::string url_;
+
+    DISALLOW_COPY_AND_ASSIGN(DhcpQuery);
+  };
+
+  // Virtual methods introduced to allow unit testing.
+  virtual ProxyScriptFetcher* ImplCreateScriptFetcher();
+  virtual DhcpQuery* ImplCreateDhcpQuery();
+  virtual base::TimeDelta ImplGetTimeout() const;
+
+ private:
+  // Event/state transition handlers
+  void OnDhcpQueryDone(scoped_refptr<DhcpQuery> dhcp_query);
+  void OnTimeout();
+  void OnFetcherDone(int result);
+  void TransitionToFinish();
+
+  // Current state of this state machine.
+  State state_;
+
+  // A network error indicating result of operation.
+  int result_;
+
+  // Empty string or the PAC script downloaded.
+  string16 pac_script_;
+
+  // Empty URL or the PAC URL configured in DHCP.
+  GURL pac_url_;
+
+  // Callback to let our client know we're done. Invalid in states
+  // START, FINISH and CANCEL.
+  net::CompletionCallback callback_;
+
+  // Fetcher to retrieve PAC files once URL is known.
+  scoped_ptr<ProxyScriptFetcher> script_fetcher_;
+
+  // Implements a timeout on the call to the Win32 DHCP API.
+  base::OneShotTimer<DhcpProxyScriptAdapterFetcher> wait_timer_;
+
+  URLRequestContext* const url_request_context_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpProxyScriptAdapterFetcher);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_DHCP_PROXY_SCRIPT_ADAPTER_FETCHER_WIN_H_
diff --git a/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc b/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc
new file mode 100644
index 0000000..480f2f6
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc
@@ -0,0 +1,297 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/dhcp_proxy_script_adapter_fetcher_win.h"
+
+#include "base/perftimer.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/test_timeouts.h"
+#include "base/timer.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_completion_callback.h"
+#include "net/proxy/mock_proxy_script_fetcher.h"
+#include "net/proxy/proxy_script_fetcher_impl.h"
+#include "net/test/test_server.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+const char* const kPacUrl = "http://pacserver/script.pac";
+
+// In net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc there are a few
+// tests that exercise DhcpProxyScriptAdapterFetcher end-to-end along with
+// DhcpProxyScriptFetcherWin, i.e. it tests the end-to-end usage of Win32
+// APIs and the network.  In this file we test only by stubbing out
+// functionality.
+
+// Version of DhcpProxyScriptAdapterFetcher that mocks out dependencies
+// to allow unit testing.
+class MockDhcpProxyScriptAdapterFetcher
+    : public DhcpProxyScriptAdapterFetcher {
+ public:
+  explicit MockDhcpProxyScriptAdapterFetcher(URLRequestContext* context)
+      : DhcpProxyScriptAdapterFetcher(context),
+        dhcp_delay_(base::TimeDelta::FromMilliseconds(1)),
+        timeout_(TestTimeouts::action_timeout()),
+        configured_url_(kPacUrl),
+        fetcher_delay_ms_(1),
+        fetcher_result_(OK),
+        pac_script_("bingo") {
+  }
+
+  void Cancel() {
+    DhcpProxyScriptAdapterFetcher::Cancel();
+    fetcher_ = NULL;
+  }
+
+  virtual ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE {
+    // We don't maintain ownership of the fetcher, it is transferred to
+    // the caller.
+    fetcher_ = new MockProxyScriptFetcher();
+    if (fetcher_delay_ms_ != -1) {
+      fetcher_timer_.Start(FROM_HERE,
+          base::TimeDelta::FromMilliseconds(fetcher_delay_ms_),
+          this, &MockDhcpProxyScriptAdapterFetcher::OnFetcherTimer);
+    }
+    return fetcher_;
+  }
+
+  class DelayingDhcpQuery : public DhcpQuery {
+   public:
+    explicit DelayingDhcpQuery()
+        : DhcpQuery(),
+          test_finished_event_(true, false) {
+    }
+
+    std::string ImplGetPacURLFromDhcp(
+        const std::string& adapter_name) OVERRIDE {
+      PerfTimer timer;
+      test_finished_event_.TimedWait(dhcp_delay_);
+      return configured_url_;
+    }
+
+    base::WaitableEvent test_finished_event_;
+    base::TimeDelta dhcp_delay_;
+    std::string configured_url_;
+  };
+
+  virtual DhcpQuery* ImplCreateDhcpQuery() OVERRIDE {
+    dhcp_query_ = new DelayingDhcpQuery();
+    dhcp_query_->dhcp_delay_ = dhcp_delay_;
+    dhcp_query_->configured_url_ = configured_url_;
+    return dhcp_query_;
+  }
+
+  // Use a shorter timeout so tests can finish more quickly.
+  virtual base::TimeDelta ImplGetTimeout() const OVERRIDE {
+    return timeout_;
+  }
+
+  void OnFetcherTimer() {
+    // Note that there is an assumption by this mock implementation that
+    // DhcpProxyScriptAdapterFetcher::Fetch will call ImplCreateScriptFetcher
+    // and call Fetch on the fetcher before the message loop is re-entered.
+    // This holds true today, but if you hit this DCHECK the problem can
+    // possibly be resolved by having a separate subclass of
+    // MockProxyScriptFetcher that adds the delay internally (instead of
+    // the simple approach currently used in ImplCreateScriptFetcher above).
+    DCHECK(fetcher_ && fetcher_->has_pending_request());
+    fetcher_->NotifyFetchCompletion(fetcher_result_, pac_script_);
+    fetcher_ = NULL;
+  }
+
+  bool IsWaitingForFetcher() const {
+    return state() == STATE_WAIT_URL;
+  }
+
+  bool WasCancelled() const {
+    return state() == STATE_CANCEL;
+  }
+
+  void FinishTest() {
+    DCHECK(dhcp_query_);
+    dhcp_query_->test_finished_event_.Signal();
+  }
+
+  base::TimeDelta dhcp_delay_;
+  base::TimeDelta timeout_;
+  std::string configured_url_;
+  int fetcher_delay_ms_;
+  int fetcher_result_;
+  std::string pac_script_;
+  MockProxyScriptFetcher* fetcher_;
+  base::OneShotTimer<MockDhcpProxyScriptAdapterFetcher> fetcher_timer_;
+  scoped_refptr<DelayingDhcpQuery> dhcp_query_;
+};
+
+class FetcherClient {
+ public:
+  FetcherClient()
+      : url_request_context_(new TestURLRequestContext()),
+        fetcher_(
+            new MockDhcpProxyScriptAdapterFetcher(url_request_context_.get())) {
+  }
+
+  void WaitForResult(int expected_error) {
+    EXPECT_EQ(expected_error, callback_.WaitForResult());
+  }
+
+  void RunTest() {
+    fetcher_->Fetch("adapter name", callback_.callback());
+  }
+
+  void FinishTestAllowCleanup() {
+    fetcher_->FinishTest();
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  TestCompletionCallback callback_;
+  scoped_ptr<URLRequestContext> url_request_context_;
+  scoped_ptr<MockDhcpProxyScriptAdapterFetcher> fetcher_;
+  string16 pac_text_;
+};
+
+TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLNotInDhcp) {
+  FetcherClient client;
+  client.fetcher_->configured_url_ = "";
+  client.RunTest();
+  client.WaitForResult(ERR_PAC_NOT_IN_DHCP);
+  ASSERT_TRUE(client.fetcher_->DidFinish());
+  EXPECT_EQ(ERR_PAC_NOT_IN_DHCP, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript());
+}
+
+TEST(DhcpProxyScriptAdapterFetcher, NormalCaseURLInDhcp) {
+  FetcherClient client;
+  client.RunTest();
+  client.WaitForResult(OK);
+  ASSERT_TRUE(client.fetcher_->DidFinish());
+  EXPECT_EQ(OK, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L"bingo"), client.fetcher_->GetPacScript());
+  EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL());
+}
+
+TEST(DhcpProxyScriptAdapterFetcher, TimeoutDuringDhcp) {
+  // Does a Fetch() with a long enough delay on accessing DHCP that the
+  // fetcher should time out.  This is to test a case manual testing found,
+  // where under certain circumstances (e.g. adapter enabled for DHCP and
+  // needs to retrieve its configuration from DHCP, but no DHCP server
+  // present on the network) accessing DHCP can take on the order of tens
+  // of seconds.
+  FetcherClient client;
+  client.fetcher_->dhcp_delay_ = TestTimeouts::action_max_timeout();
+  client.fetcher_->timeout_ = base::TimeDelta::FromMilliseconds(25);
+
+  PerfTimer timer;
+  client.RunTest();
+  // An error different from this would be received if the timeout didn't
+  // kick in.
+  client.WaitForResult(ERR_TIMED_OUT);
+
+  ASSERT_TRUE(client.fetcher_->DidFinish());
+  EXPECT_EQ(ERR_TIMED_OUT, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript());
+  EXPECT_EQ(GURL(), client.fetcher_->GetPacURL());
+  client.FinishTestAllowCleanup();
+}
+
+TEST(DhcpProxyScriptAdapterFetcher, CancelWhileDhcp) {
+  FetcherClient client;
+  client.RunTest();
+  client.fetcher_->Cancel();
+  MessageLoop::current()->RunUntilIdle();
+  ASSERT_FALSE(client.fetcher_->DidFinish());
+  ASSERT_TRUE(client.fetcher_->WasCancelled());
+  EXPECT_EQ(ERR_ABORTED, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript());
+  EXPECT_EQ(GURL(), client.fetcher_->GetPacURL());
+  client.FinishTestAllowCleanup();
+}
+
+TEST(DhcpProxyScriptAdapterFetcher, CancelWhileFetcher) {
+  FetcherClient client;
+  // This causes the mock fetcher not to pretend the
+  // fetcher finishes after a timeout.
+  client.fetcher_->fetcher_delay_ms_ = -1;
+  client.RunTest();
+  int max_loops = 4;
+  while (!client.fetcher_->IsWaitingForFetcher() && max_loops--) {
+    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
+    MessageLoop::current()->RunUntilIdle();
+  }
+  client.fetcher_->Cancel();
+  MessageLoop::current()->RunUntilIdle();
+  ASSERT_FALSE(client.fetcher_->DidFinish());
+  ASSERT_TRUE(client.fetcher_->WasCancelled());
+  EXPECT_EQ(ERR_ABORTED, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L""), client.fetcher_->GetPacScript());
+  // GetPacURL() still returns the URL fetched in this case.
+  EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL());
+  client.FinishTestAllowCleanup();
+}
+
+TEST(DhcpProxyScriptAdapterFetcher, CancelAtCompletion) {
+  FetcherClient client;
+  client.RunTest();
+  client.WaitForResult(OK);
+  client.fetcher_->Cancel();
+  // Canceling after you're done should have no effect, so these
+  // are identical expectations to the NormalCaseURLInDhcp test.
+  ASSERT_TRUE(client.fetcher_->DidFinish());
+  EXPECT_EQ(OK, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L"bingo"), client.fetcher_->GetPacScript());
+  EXPECT_EQ(GURL(kPacUrl), client.fetcher_->GetPacURL());
+  client.FinishTestAllowCleanup();
+}
+
+// Does a real fetch on a mock DHCP configuration.
+class MockDhcpRealFetchProxyScriptAdapterFetcher
+    : public MockDhcpProxyScriptAdapterFetcher {
+ public:
+  explicit MockDhcpRealFetchProxyScriptAdapterFetcher(
+      URLRequestContext* context)
+      : MockDhcpProxyScriptAdapterFetcher(context),
+        url_request_context_(context) {
+  }
+
+  // Returns a real proxy script fetcher.
+  ProxyScriptFetcher* ImplCreateScriptFetcher() OVERRIDE {
+    ProxyScriptFetcher* fetcher =
+        new ProxyScriptFetcherImpl(url_request_context_);
+    return fetcher;
+  }
+
+  URLRequestContext* url_request_context_;
+};
+
+TEST(DhcpProxyScriptAdapterFetcher, MockDhcpRealFetch) {
+  TestServer test_server(
+      TestServer::TYPE_HTTP,
+      net::TestServer::kLocalhost,
+      FilePath(FILE_PATH_LITERAL("net/data/proxy_script_fetcher_unittest")));
+  ASSERT_TRUE(test_server.Start());
+
+  GURL configured_url = test_server.GetURL("files/downloadable.pac");
+
+  FetcherClient client;
+  TestURLRequestContext url_request_context;
+  client.fetcher_.reset(
+      new MockDhcpRealFetchProxyScriptAdapterFetcher(
+          &url_request_context));
+  client.fetcher_->configured_url_ = configured_url.spec();
+  client.RunTest();
+  client.WaitForResult(OK);
+  ASSERT_TRUE(client.fetcher_->DidFinish());
+  EXPECT_EQ(OK, client.fetcher_->GetResult());
+  EXPECT_EQ(string16(L"-downloadable.pac-\n"), client.fetcher_->GetPacScript());
+  EXPECT_EQ(configured_url,
+            client.fetcher_->GetPacURL());
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher.cc b/src/net/proxy/dhcp_proxy_script_fetcher.cc
new file mode 100644
index 0000000..ba2c137
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/dhcp_proxy_script_fetcher.h"
+
+#include "net/base/net_errors.h"
+
+namespace net {
+
+std::string DhcpProxyScriptFetcher::GetFetcherName() const {
+  return "";
+}
+
+DhcpProxyScriptFetcher::DhcpProxyScriptFetcher() {}
+
+DhcpProxyScriptFetcher::~DhcpProxyScriptFetcher() {}
+
+DoNothingDhcpProxyScriptFetcher::DoNothingDhcpProxyScriptFetcher() {}
+
+DoNothingDhcpProxyScriptFetcher::~DoNothingDhcpProxyScriptFetcher() {}
+
+int DoNothingDhcpProxyScriptFetcher::Fetch(
+    string16* utf16_text, const CompletionCallback& callback) {
+  return ERR_NOT_IMPLEMENTED;
+}
+
+void DoNothingDhcpProxyScriptFetcher::Cancel() {}
+
+const GURL& DoNothingDhcpProxyScriptFetcher::GetPacURL() const {
+  return gurl_;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher.h b/src/net/proxy/dhcp_proxy_script_fetcher.h
new file mode 100644
index 0000000..3130d7b
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_DHCP_SCRIPT_FETCHER_H_
+#define NET_PROXY_DHCP_SCRIPT_FETCHER_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/string16.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_script_fetcher.h"
+
+namespace net {
+
+// Interface for classes that can fetch a proxy script as configured via DHCP.
+//
+// The Fetch method on this interface tries to retrieve the most appropriate
+// PAC script configured via DHCP.
+//
+// Normally there are zero or one DHCP scripts configured, but in the
+// presence of multiple adapters with DHCP enabled, the fetcher resolves
+// which PAC script to use if one or more are available.
+class NET_EXPORT_PRIVATE DhcpProxyScriptFetcher {
+ public:
+  // Destruction should cancel any outstanding requests.
+  virtual ~DhcpProxyScriptFetcher();
+
+  // Attempts to retrieve the most appropriate PAC script configured via DHCP,
+  // and invokes |callback| on completion.
+  //
+  // Returns OK on success, otherwise the error code. If the return code is
+  // ERR_IO_PENDING, then the request completes asynchronously, and |callback|
+  // will be invoked later with the final error code.
+  //
+  // After synchronous or asynchronous completion with a result code of OK,
+  // |*utf16_text| is filled with the response. On failure, the result text is
+  // an empty string, and the result code is a network error. Some special
+  // network errors that may occur are:
+  //
+  //    ERR_PAC_NOT_IN_DHCP   -- no script configured in DHCP.
+  //
+  //    The following all indicate there was one or more script configured
+  //    in DHCP but all failed to download, and the error for the most
+  //    preferred adapter that had a script configured was what the error
+  //    code says:
+  //
+  //      ERR_TIMED_OUT         -- fetch took too long to complete.
+  //      ERR_FILE_TOO_BIG      -- response body was too large.
+  //      ERR_PAC_STATUS_NOT_OK -- script failed to download.
+  //      ERR_NOT_IMPLEMENTED   -- script required authentication.
+  //
+  // If the request is cancelled (either using the "Cancel()" method or by
+  // deleting |this|), then no callback is invoked.
+  //
+  // Only one fetch is allowed to be outstanding at a time.
+  virtual int Fetch(string16* utf16_text,
+                    const CompletionCallback& callback) = 0;
+
+  // Aborts the in-progress fetch (if any).
+  virtual void Cancel() = 0;
+
+  // After successful completion of |Fetch()|, this will return the URL
+  // retrieved from DHCP.  It is reset if/when |Fetch()| is called again.
+  virtual const GURL& GetPacURL() const = 0;
+
+  // Intended for unit tests only, so they can test that factories return
+  // the right types under given circumstances.
+  virtual std::string GetFetcherName() const;
+
+ protected:
+  DhcpProxyScriptFetcher();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DhcpProxyScriptFetcher);
+};
+
+// A do-nothing retriever, always returns synchronously with
+// ERR_NOT_IMPLEMENTED result and empty text.
+class NET_EXPORT_PRIVATE DoNothingDhcpProxyScriptFetcher
+    : public DhcpProxyScriptFetcher {
+ public:
+  DoNothingDhcpProxyScriptFetcher();
+  virtual ~DoNothingDhcpProxyScriptFetcher();
+
+  virtual int Fetch(string16* utf16_text,
+                    const CompletionCallback& callback) OVERRIDE;
+  virtual void Cancel() OVERRIDE;
+  virtual const GURL& GetPacURL() const OVERRIDE;
+ private:
+  GURL gurl_;
+  DISALLOW_COPY_AND_ASSIGN(DoNothingDhcpProxyScriptFetcher);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_DHCP_SCRIPT_FETCHER_H_
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher_factory.cc b/src/net/proxy/dhcp_proxy_script_fetcher_factory.cc
new file mode 100644
index 0000000..01ede05
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher_factory.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/dhcp_proxy_script_fetcher_factory.h"
+
+#include "net/base/net_errors.h"
+#include "net/proxy/dhcp_proxy_script_fetcher.h"
+
+#if defined(OS_WIN)
+#include "net/proxy/dhcp_proxy_script_fetcher_win.h"
+#endif
+
+namespace net {
+
+DhcpProxyScriptFetcherFactory::DhcpProxyScriptFetcherFactory()
+    : feature_enabled_(false) {
+  set_enabled(true);
+}
+
+DhcpProxyScriptFetcher* DhcpProxyScriptFetcherFactory::Create(
+    URLRequestContext* context) {
+  if (!feature_enabled_) {
+    return new DoNothingDhcpProxyScriptFetcher();
+  } else {
+    DCHECK(IsSupported());
+    DhcpProxyScriptFetcher* ret = NULL;
+#if defined(OS_WIN)
+    ret = new DhcpProxyScriptFetcherWin(context);
+#endif
+    DCHECK(ret);
+    return ret;
+  }
+}
+
+void DhcpProxyScriptFetcherFactory::set_enabled(bool enabled) {
+  if (IsSupported()) {
+    feature_enabled_ = enabled;
+  }
+}
+
+bool DhcpProxyScriptFetcherFactory::enabled() const {
+  return feature_enabled_;
+}
+
+// static
+bool DhcpProxyScriptFetcherFactory::IsSupported() {
+#if defined(OS_WIN)
+  return true;
+#else
+  return false;
+#endif
+}
+
+}  // namespace net
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher_factory.h b/src/net/proxy/dhcp_proxy_script_fetcher_factory.h
new file mode 100644
index 0000000..147435d
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher_factory.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_
+#define NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_
+
+#include "base/basictypes.h"
+#include "base/memory/singleton.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class DhcpProxyScriptFetcher;
+class URLRequestContext;
+
+// Factory object for creating the appropriate concrete base class of
+// DhcpProxyScriptFetcher for your operating system and settings.
+//
+// You might think we could just implement a DHCP client at the protocol
+// level and have cross-platform support for retrieving PAC configuration
+// from DHCP, but unfortunately the DHCP protocol assumes there is a single
+// client per machine (specifically per network interface card), and there
+// is an implicit state machine between the client and server, so adding a
+// second client to the machine would not be advisable (see e.g. some
+// discussion of what can happen at this URL:
+// http://www.net.princeton.edu/multi-dhcp-one-interface-handling.html).
+//
+// Therefore, we have platform-specific implementations, and so we use
+// this factory to select the right one.
+class NET_EXPORT DhcpProxyScriptFetcherFactory {
+ public:
+  // Creates a new factory object with default settings.
+  DhcpProxyScriptFetcherFactory();
+
+  // Ownership is transferred to the caller. url_request_context must be valid
+  // and its lifetime must exceed that of the returned DhcpProxyScriptFetcher.
+  //
+  // Note that while a request is in progress, the fetcher may be holding a
+  // reference to |url_request_context|. Be careful not to create cycles
+  // between the fetcher and the context; you can break such cycles by calling
+  // Cancel().
+  DhcpProxyScriptFetcher* Create(URLRequestContext* url_request_context);
+
+  // Attempts to enable/disable the DHCP WPAD feature.  Does nothing
+  // if |IsSupported()| returns false.
+  //
+  // The default is |enabled() == true|.
+  void set_enabled(bool enabled);
+
+  // Returns true if the DHCP WPAD feature is enabled.  Always returns
+  // false if |IsSupported()| is false.
+  bool enabled() const;
+
+  // Returns true if the DHCP WPAD feature is supported on the current
+  // operating system.
+  static bool IsSupported();
+
+ private:
+  bool feature_enabled_;
+
+  DISALLOW_COPY_AND_ASSIGN(DhcpProxyScriptFetcherFactory);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_DHCP_SCRIPT_FETCHER_FACTORY_H_
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher_factory_unittest.cc b/src/net/proxy/dhcp_proxy_script_fetcher_factory_unittest.cc
new file mode 100644
index 0000000..9eb7c67
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher_factory_unittest.cc
@@ -0,0 +1,59 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/dhcp_proxy_script_fetcher.h"
+#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+TEST(DhcpProxyScriptFetcherFactoryTest, DoNothingWhenDisabled) {
+  DhcpProxyScriptFetcherFactory factory;
+  factory.set_enabled(false);
+  scoped_ptr<DhcpProxyScriptFetcher> fetcher(factory.Create(NULL));
+  EXPECT_EQ("", fetcher->GetFetcherName());
+}
+
+#if defined(OS_WIN)
+TEST(DhcpProxyScriptFetcherFactoryTest, WindowsFetcherOnWindows) {
+  DhcpProxyScriptFetcherFactory factory;
+  factory.set_enabled(true);
+
+  scoped_ptr<TestURLRequestContext> context(new TestURLRequestContext());
+  scoped_ptr<DhcpProxyScriptFetcher> fetcher(factory.Create(context.get()));
+  EXPECT_EQ("win", fetcher->GetFetcherName());
+}
+#endif  // defined(OS_WIN)
+
+TEST(DhcpProxyScriptFetcherFactoryTest, IsSupported) {
+#if defined(OS_WIN)
+  ASSERT_TRUE(DhcpProxyScriptFetcherFactory::IsSupported());
+#else
+  ASSERT_FALSE(DhcpProxyScriptFetcherFactory::IsSupported());
+#endif  // defined(OS_WIN)
+}
+
+TEST(DhcpProxyScriptFetcherFactoryTest, SetEnabled) {
+  DhcpProxyScriptFetcherFactory factory;
+#if defined(OS_WIN)
+  EXPECT_TRUE(factory.enabled());
+#else
+  EXPECT_FALSE(factory.enabled());
+#endif  // defined(OS_WIN)
+
+  factory.set_enabled(false);
+  EXPECT_FALSE(factory.enabled());
+
+  factory.set_enabled(true);
+#if defined(OS_WIN)
+  EXPECT_TRUE(factory.enabled());
+#else
+  EXPECT_FALSE(factory.enabled());
+#endif  // defined(OS_WIN)
+}
+
+}  // namespace
+}  // namespace net
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher_win.cc b/src/net/proxy/dhcp_proxy_script_fetcher_win.cc
new file mode 100644
index 0000000..aa68c31
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher_win.cc
@@ -0,0 +1,375 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/dhcp_proxy_script_fetcher_win.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/metrics/histogram.h"
+#include "base/perftimer.h"
+#include "base/threading/worker_pool.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h"
+
+#include <winsock2.h>
+#include <iphlpapi.h>
+#pragma comment(lib, "iphlpapi.lib")
+
+namespace {
+
+// How long to wait at maximum after we get results (a PAC file or
+// knowledge that no PAC file is configured) from whichever network
+// adapter finishes first.
+const int kMaxWaitAfterFirstResultMs = 400;
+
+const int kGetAdaptersAddressesErrors[] = {
+  ERROR_ADDRESS_NOT_ASSOCIATED,
+  ERROR_BUFFER_OVERFLOW,
+  ERROR_INVALID_PARAMETER,
+  ERROR_NOT_ENOUGH_MEMORY,
+  ERROR_NO_DATA,
+};
+
+}  // namespace
+
+namespace net {
+
+DhcpProxyScriptFetcherWin::DhcpProxyScriptFetcherWin(
+    URLRequestContext* url_request_context)
+    : state_(STATE_START),
+      num_pending_fetchers_(0),
+      destination_string_(NULL),
+      url_request_context_(url_request_context) {
+  DCHECK(url_request_context_);
+}
+
+DhcpProxyScriptFetcherWin::~DhcpProxyScriptFetcherWin() {
+  // Count as user-initiated if we are not yet in STATE_DONE.
+  Cancel();
+
+  // The WeakPtr we passed to the worker thread may be destroyed on the
+  // worker thread.  This detaches any outstanding WeakPtr state from
+  // the current thread.
+  base::SupportsWeakPtr<DhcpProxyScriptFetcherWin>::DetachFromThread();
+}
+
+int DhcpProxyScriptFetcherWin::Fetch(string16* utf16_text,
+                                     const CompletionCallback& callback) {
+  DCHECK(CalledOnValidThread());
+  if (state_ != STATE_START && state_ != STATE_DONE) {
+    NOTREACHED();
+    return ERR_UNEXPECTED;
+  }
+
+  fetch_start_time_ = base::TimeTicks::Now();
+
+  state_ = STATE_WAIT_ADAPTERS;
+  callback_ = callback;
+  destination_string_ = utf16_text;
+
+  last_query_ = ImplCreateAdapterQuery();
+  base::WorkerPool::PostTaskAndReply(
+      FROM_HERE,
+      base::Bind(
+          &DhcpProxyScriptFetcherWin::AdapterQuery::GetCandidateAdapterNames,
+          last_query_.get()),
+      base::Bind(
+          &DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone,
+          AsWeakPtr(),
+          last_query_),
+      true);
+
+  return ERR_IO_PENDING;
+}
+
+void DhcpProxyScriptFetcherWin::Cancel() {
+  DCHECK(CalledOnValidThread());
+
+  if (state_ != STATE_DONE) {
+    // We only count this stat if the cancel was explicitly initiated by
+    // our client, and if we weren't already in STATE_DONE.
+    UMA_HISTOGRAM_TIMES("Net.DhcpWpadCancelTime",
+                        base::TimeTicks::Now() - fetch_start_time_);
+  }
+
+  CancelImpl();
+}
+
+void DhcpProxyScriptFetcherWin::CancelImpl() {
+  DCHECK(CalledOnValidThread());
+
+  if (state_ != STATE_DONE) {
+    callback_.Reset();
+    wait_timer_.Stop();
+    state_ = STATE_DONE;
+
+    for (FetcherVector::iterator it = fetchers_.begin();
+         it != fetchers_.end();
+         ++it) {
+      (*it)->Cancel();
+    }
+
+    fetchers_.clear();
+  }
+}
+
+void DhcpProxyScriptFetcherWin::OnGetCandidateAdapterNamesDone(
+    scoped_refptr<AdapterQuery> query) {
+  DCHECK(CalledOnValidThread());
+
+  // This can happen if this object is reused for multiple queries,
+  // and a previous query was cancelled before it completed.
+  if (query.get() != last_query_.get())
+    return;
+  last_query_ = NULL;
+
+  // Enable unit tests to wait for this to happen; in production this function
+  // call is a no-op.
+  ImplOnGetCandidateAdapterNamesDone();
+
+  // We may have been cancelled.
+  if (state_ != STATE_WAIT_ADAPTERS)
+    return;
+
+  state_ = STATE_NO_RESULTS;
+
+  const std::set<std::string>& adapter_names = query->adapter_names();
+
+  if (adapter_names.empty()) {
+    TransitionToDone();
+    return;
+  }
+
+  for (std::set<std::string>::const_iterator it = adapter_names.begin();
+       it != adapter_names.end();
+       ++it) {
+    DhcpProxyScriptAdapterFetcher* fetcher(ImplCreateAdapterFetcher());
+    fetcher->Fetch(
+        *it, base::Bind(&DhcpProxyScriptFetcherWin::OnFetcherDone,
+                        base::Unretained(this)));
+    fetchers_.push_back(fetcher);
+  }
+  num_pending_fetchers_ = fetchers_.size();
+}
+
+std::string DhcpProxyScriptFetcherWin::GetFetcherName() const {
+  DCHECK(CalledOnValidThread());
+  return "win";
+}
+
+const GURL& DhcpProxyScriptFetcherWin::GetPacURL() const {
+  DCHECK(CalledOnValidThread());
+  DCHECK_EQ(state_, STATE_DONE);
+
+  return pac_url_;
+}
+
+void DhcpProxyScriptFetcherWin::OnFetcherDone(int result) {
+  DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
+
+  if (--num_pending_fetchers_ == 0) {
+    TransitionToDone();
+    return;
+  }
+
+  // If the only pending adapters are those less preferred than one
+  // with a valid PAC script, we do not need to wait any longer.
+  for (FetcherVector::iterator it = fetchers_.begin();
+       it != fetchers_.end();
+       ++it) {
+    bool did_finish = (*it)->DidFinish();
+    int result = (*it)->GetResult();
+    if (did_finish && result == OK) {
+      TransitionToDone();
+      return;
+    }
+    if (!did_finish || result != ERR_PAC_NOT_IN_DHCP) {
+      break;
+    }
+  }
+
+  // Once we have a single result, we set a maximum on how long to wait
+  // for the rest of the results.
+  if (state_ == STATE_NO_RESULTS) {
+    state_ = STATE_SOME_RESULTS;
+    wait_timer_.Start(FROM_HERE,
+        ImplGetMaxWait(), this, &DhcpProxyScriptFetcherWin::OnWaitTimer);
+  }
+}
+
+void DhcpProxyScriptFetcherWin::OnWaitTimer() {
+  DCHECK_EQ(state_, STATE_SOME_RESULTS);
+
+  // These are intended to help us understand whether our timeout may
+  // be too aggressive or not aggressive enough.
+  UMA_HISTOGRAM_COUNTS_100("Net.DhcpWpadNumAdaptersAtWaitTimer",
+                           fetchers_.size());
+  UMA_HISTOGRAM_COUNTS_100("Net.DhcpWpadNumPendingAdaptersAtWaitTimer",
+                           num_pending_fetchers_);
+
+  TransitionToDone();
+}
+
+void DhcpProxyScriptFetcherWin::TransitionToDone() {
+  DCHECK(state_ == STATE_NO_RESULTS || state_ == STATE_SOME_RESULTS);
+
+  int result = ERR_PAC_NOT_IN_DHCP;  // Default if no fetchers.
+  if (!fetchers_.empty()) {
+    // Scan twice for the result; once through the whole list for success,
+    // then if no success, return result for most preferred network adapter,
+    // preferring "real" network errors to the ERR_PAC_NOT_IN_DHCP error.
+    // Default to ERR_ABORTED if no fetcher completed.
+    result = ERR_ABORTED;
+    for (FetcherVector::iterator it = fetchers_.begin();
+         it != fetchers_.end();
+         ++it) {
+      if ((*it)->DidFinish() && (*it)->GetResult() == OK) {
+        result = OK;
+        *destination_string_ = (*it)->GetPacScript();
+        pac_url_ = (*it)->GetPacURL();
+        break;
+      }
+    }
+    if (result != OK) {
+      destination_string_->clear();
+      for (FetcherVector::iterator it = fetchers_.begin();
+           it != fetchers_.end();
+           ++it) {
+        if ((*it)->DidFinish()) {
+          result = (*it)->GetResult();
+          if (result != ERR_PAC_NOT_IN_DHCP) {
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  CompletionCallback callback = callback_;
+  CancelImpl();
+  DCHECK_EQ(state_, STATE_DONE);
+  DCHECK(fetchers_.empty());
+  DCHECK(callback_.is_null());  // Invariant of data.
+
+  UMA_HISTOGRAM_TIMES("Net.DhcpWpadCompletionTime",
+                      base::TimeTicks::Now() - fetch_start_time_);
+
+  if (result != OK) {
+    UMA_HISTOGRAM_CUSTOM_ENUMERATION(
+        "Net.DhcpWpadFetchError", std::abs(result), GetAllErrorCodesForUma());
+  }
+
+  // We may be deleted re-entrantly within this outcall.
+  callback.Run(result);
+}
+
+int DhcpProxyScriptFetcherWin::num_pending_fetchers() const {
+  return num_pending_fetchers_;
+}
+
+URLRequestContext* DhcpProxyScriptFetcherWin::url_request_context() const {
+  return url_request_context_;
+}
+
+DhcpProxyScriptAdapterFetcher*
+    DhcpProxyScriptFetcherWin::ImplCreateAdapterFetcher() {
+  return new DhcpProxyScriptAdapterFetcher(url_request_context_);
+}
+
+DhcpProxyScriptFetcherWin::AdapterQuery*
+    DhcpProxyScriptFetcherWin::ImplCreateAdapterQuery() {
+  return new AdapterQuery();
+}
+
+base::TimeDelta DhcpProxyScriptFetcherWin::ImplGetMaxWait() {
+  return base::TimeDelta::FromMilliseconds(kMaxWaitAfterFirstResultMs);
+}
+
+bool DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(
+    std::set<std::string>* adapter_names) {
+  DCHECK(adapter_names);
+  adapter_names->clear();
+
+  // The GetAdaptersAddresses MSDN page recommends using a size of 15000 to
+  // avoid reallocation.
+  ULONG adapters_size = 15000;
+  scoped_ptr_malloc<IP_ADAPTER_ADDRESSES> adapters;
+  ULONG error = ERROR_SUCCESS;
+  int num_tries = 0;
+
+  PerfTimer time_api_access;
+  do {
+    adapters.reset(
+        reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(adapters_size)));
+    // Return only unicast addresses, and skip information we do not need.
+    error = GetAdaptersAddresses(AF_UNSPEC,
+                                 GAA_FLAG_SKIP_ANYCAST |
+                                 GAA_FLAG_SKIP_MULTICAST |
+                                 GAA_FLAG_SKIP_DNS_SERVER |
+                                 GAA_FLAG_SKIP_FRIENDLY_NAME,
+                                 NULL,
+                                 adapters.get(),
+                                 &adapters_size);
+    ++num_tries;
+  } while (error == ERROR_BUFFER_OVERFLOW && num_tries <= 3);
+
+  // This is primarily to validate our belief that the GetAdaptersAddresses API
+  // function is fast enough to call synchronously from the network thread.
+  UMA_HISTOGRAM_TIMES("Net.DhcpWpadGetAdaptersAddressesTime",
+                      time_api_access.Elapsed());
+
+  if (error != ERROR_SUCCESS) {
+    UMA_HISTOGRAM_CUSTOM_ENUMERATION(
+        "Net.DhcpWpadGetAdaptersAddressesError",
+        error,
+        base::CustomHistogram::ArrayToCustomRanges(
+            kGetAdaptersAddressesErrors,
+            arraysize(kGetAdaptersAddressesErrors)));
+  }
+
+  if (error == ERROR_NO_DATA) {
+    // There are no adapters that we care about.
+    return true;
+  }
+
+  if (error != ERROR_SUCCESS) {
+    LOG(WARNING) << "Unexpected error retrieving WPAD configuration from DHCP.";
+    return false;
+  }
+
+  IP_ADAPTER_ADDRESSES* adapter = NULL;
+  for (adapter = adapters.get(); adapter; adapter = adapter->Next) {
+    if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
+      continue;
+    if ((adapter->Flags & IP_ADAPTER_DHCP_ENABLED) == 0)
+      continue;
+
+    DCHECK(adapter->AdapterName);
+    adapter_names->insert(adapter->AdapterName);
+  }
+
+  return true;
+}
+
+DhcpProxyScriptFetcherWin::AdapterQuery::AdapterQuery() {
+}
+
+DhcpProxyScriptFetcherWin::AdapterQuery::~AdapterQuery() {
+}
+
+void DhcpProxyScriptFetcherWin::AdapterQuery::GetCandidateAdapterNames() {
+  ImplGetCandidateAdapterNames(&adapter_names_);
+}
+
+const std::set<std::string>&
+    DhcpProxyScriptFetcherWin::AdapterQuery::adapter_names() const {
+  return adapter_names_;
+}
+
+bool DhcpProxyScriptFetcherWin::AdapterQuery::ImplGetCandidateAdapterNames(
+    std::set<std::string>* adapter_names) {
+  return DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(adapter_names);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher_win.h b/src/net/proxy/dhcp_proxy_script_fetcher_win.h
new file mode 100644
index 0000000..e123dfc
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher_win.h
@@ -0,0 +1,169 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_DHCP_PROXY_SCRIPT_FETCHER_WIN_H_
+#define NET_PROXY_DHCP_PROXY_SCRIPT_FETCHER_WIN_H_
+
+#include <set>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "base/message_loop_proxy.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/time.h"
+#include "base/timer.h"
+#include "net/proxy/dhcp_proxy_script_fetcher.h"
+
+namespace net {
+
+class DhcpProxyScriptAdapterFetcher;
+class URLRequestContext;
+
+// Windows-specific implementation.
+class NET_EXPORT_PRIVATE DhcpProxyScriptFetcherWin
+    : public DhcpProxyScriptFetcher,
+      public base::SupportsWeakPtr<DhcpProxyScriptFetcherWin>,
+      NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+  // Creates a DhcpProxyScriptFetcherWin that issues requests through
+  // |url_request_context|. |url_request_context| must remain valid for
+  // the lifetime of DhcpProxyScriptFetcherWin.
+  explicit DhcpProxyScriptFetcherWin(URLRequestContext* url_request_context);
+  virtual ~DhcpProxyScriptFetcherWin();
+
+  // DhcpProxyScriptFetcher implementation.
+  int Fetch(string16* utf16_text,
+            const net::CompletionCallback& callback) OVERRIDE;
+  void Cancel() OVERRIDE;
+  const GURL& GetPacURL() const OVERRIDE;
+  std::string GetFetcherName() const OVERRIDE;
+
+  // Sets |adapter_names| to contain the name of each network adapter on
+  // this machine that has DHCP enabled and is not a loop-back adapter. Returns
+  // false on error.
+  static bool GetCandidateAdapterNames(std::set<std::string>* adapter_names);
+
+ protected:
+  int num_pending_fetchers() const;
+
+  URLRequestContext* url_request_context() const;
+
+  // This inner class encapsulate work done on a worker pool thread.
+  // The class calls GetCandidateAdapterNames, which can take a couple of
+  // hundred milliseconds.
+  class NET_EXPORT_PRIVATE AdapterQuery
+      : public base::RefCountedThreadSafe<AdapterQuery> {
+   public:
+    AdapterQuery();
+    virtual ~AdapterQuery();
+
+    // This is the method that runs on the worker pool thread.
+    void GetCandidateAdapterNames();
+
+    // This set is valid after GetCandidateAdapterNames has
+    // been run. Its lifetime is scoped by this object.
+    const std::set<std::string>& adapter_names() const;
+
+   protected:
+    // Virtual method introduced to allow unit testing.
+    virtual bool ImplGetCandidateAdapterNames(
+        std::set<std::string>* adapter_names);
+
+   private:
+    // This is constructed on the originating thread, then used on the
+    // worker thread, then used again on the originating thread only when
+    // the task has completed on the worker thread. No locking required.
+    std::set<std::string> adapter_names_;
+
+    DISALLOW_COPY_AND_ASSIGN(AdapterQuery);
+  };
+
+  // Virtual methods introduced to allow unit testing.
+  virtual DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher();
+  virtual AdapterQuery* ImplCreateAdapterQuery();
+  virtual base::TimeDelta ImplGetMaxWait();
+  virtual void ImplOnGetCandidateAdapterNamesDone() {}
+
+ private:
+  // Event/state transition handlers
+  void CancelImpl();
+  void OnGetCandidateAdapterNamesDone(scoped_refptr<AdapterQuery> query);
+  void OnFetcherDone(int result);
+  void OnWaitTimer();
+  void TransitionToDone();
+
+  // This is the outer state machine for fetching PAC configuration from
+  // DHCP.  It relies for sub-states on the state machine of the
+  // DhcpProxyScriptAdapterFetcher class.
+  //
+  // The goal of the implementation is to the following work in parallel
+  // for all network adapters that are using DHCP:
+  // a) Try to get the PAC URL configured in DHCP;
+  // b) If one is configured, try to fetch the PAC URL.
+  // c) Once this is done for all adapters, or a timeout has passed after
+  //    it has completed for the fastest adapter, return the PAC file
+  //    available for the most preferred network adapter, if any.
+  //
+  // The state machine goes from START->WAIT_ADAPTERS when it starts a
+  // worker thread to get the list of adapters with DHCP enabled.
+  // It then goes from WAIT_ADAPTERS->NO_RESULTS when it creates
+  // and starts an DhcpProxyScriptAdapterFetcher for each adapter.  It goes
+  // from NO_RESULTS->SOME_RESULTS when it gets the first result; at this
+  // point a wait timer is started.  It goes from SOME_RESULTS->DONE in
+  // two cases: All results are known, or the wait timer expired.  A call
+  // to Cancel() will also go straight to DONE from any state.  Any
+  // way the DONE state is entered, we will at that point cancel any
+  // outstanding work and return the best known PAC script or the empty
+  // string.
+  //
+  // The state machine is reset for each Fetch(), a call to which is
+  // only valid in states START and DONE, as only one Fetch() is
+  // allowed to be outstanding at any given time.
+  enum State {
+    STATE_START,
+    STATE_WAIT_ADAPTERS,
+    STATE_NO_RESULTS,
+    STATE_SOME_RESULTS,
+    STATE_DONE,
+  };
+
+  // Current state of this state machine.
+  State state_;
+
+  // Vector, in Windows' network adapter preference order, of
+  // DhcpProxyScriptAdapterFetcher objects that are or were attempting
+  // to fetch a PAC file based on DHCP configuration.
+  typedef ScopedVector<DhcpProxyScriptAdapterFetcher> FetcherVector;
+  FetcherVector fetchers_;
+
+  // Number of fetchers we are waiting for.
+  int num_pending_fetchers_;
+
+  // Lets our client know we're done. Not valid in states START or DONE.
+  net::CompletionCallback callback_;
+
+  // Pointer to string we will write results to. Not valid in states
+  // START and DONE.
+  string16* destination_string_;
+
+  // PAC URL retrieved from DHCP, if any. Valid only in state STATE_DONE.
+  GURL pac_url_;
+
+  base::OneShotTimer<DhcpProxyScriptFetcherWin> wait_timer_;
+
+  URLRequestContext* const url_request_context_;
+
+  // NULL or the AdapterQuery currently in flight.
+  scoped_refptr<AdapterQuery> last_query_;
+
+  // Time |Fetch()| was last called, 0 if never.
+  base::TimeTicks fetch_start_time_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(DhcpProxyScriptFetcherWin);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_DHCP_PROXY_SCRIPT_FETCHER_WIN_H_
diff --git a/src/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc b/src/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
new file mode 100644
index 0000000..7d474fc
--- /dev/null
+++ b/src/net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc
@@ -0,0 +1,642 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/dhcp_proxy_script_fetcher_win.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/message_loop.h"
+#include "base/perftimer.h"
+#include "base/rand_util.h"
+#include "base/test/test_timeouts.h"
+#include "base/threading/platform_thread.h"
+#include "net/base/completion_callback.h"
+#include "net/proxy/dhcp_proxy_script_adapter_fetcher_win.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(DhcpProxyScriptFetcherWin, AdapterNamesAndPacURLFromDhcp) {
+  // This tests our core Win32 implementation without any of the wrappers
+  // we layer on top to achieve asynchronous and parallel operations.
+  //
+  // We don't make assumptions about the environment this unit test is
+  // running in, so it just exercises the code to make sure there
+  // is no crash and no error returned, but does not assert on the number
+  // of interfaces or the information returned via DHCP.
+  std::set<std::string> adapter_names;
+  DhcpProxyScriptFetcherWin::GetCandidateAdapterNames(&adapter_names);
+  for (std::set<std::string>::const_iterator it = adapter_names.begin();
+       it != adapter_names.end();
+       ++it) {
+    const std::string& adapter_name = *it;
+    std::string pac_url =
+        DhcpProxyScriptAdapterFetcher::GetPacURLFromDhcp(adapter_name);
+    printf("Adapter '%s' has PAC URL '%s' configured in DHCP.\n",
+           adapter_name.c_str(),
+           pac_url.c_str());
+  }
+}
+
+// Helper for RealFetch* tests below.
+class RealFetchTester {
+ public:
+  RealFetchTester()
+      : context_(new TestURLRequestContext),
+        fetcher_(new DhcpProxyScriptFetcherWin(context_.get())),
+        finished_(false),
+        on_completion_is_error_(false) {
+    // Make sure the test ends.
+    timeout_.Start(FROM_HERE,
+        base::TimeDelta::FromSeconds(5), this, &RealFetchTester::OnTimeout);
+  }
+
+  void RunTest() {
+    int result = fetcher_->Fetch(
+        &pac_text_,
+        base::Bind(&RealFetchTester::OnCompletion, base::Unretained(this)));
+    if (result != ERR_IO_PENDING)
+      finished_ = true;
+  }
+
+  void RunTestWithCancel() {
+    RunTest();
+    fetcher_->Cancel();
+  }
+
+  void RunTestWithDeferredCancel() {
+    // Put the cancellation into the queue before even running the
+    // test to avoid the chance of one of the adapter fetcher worker
+    // threads completing before cancellation.  See http://crbug.com/86756.
+    cancel_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(0),
+                        this, &RealFetchTester::OnCancelTimer);
+    RunTest();
+  }
+
+  void OnCompletion(int result) {
+    if (on_completion_is_error_) {
+      FAIL() << "Received completion for test in which this is error.";
+    }
+    finished_ = true;
+    printf("Result code %d PAC data length %d\n", result, pac_text_.size());
+  }
+
+  void OnTimeout() {
+    printf("Timeout!");
+    OnCompletion(0);
+  }
+
+  void OnCancelTimer() {
+    fetcher_->Cancel();
+    finished_ = true;
+  }
+
+  void WaitUntilDone() {
+    while (!finished_) {
+      MessageLoop::current()->RunUntilIdle();
+    }
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  // Attempts to give worker threads time to finish.  This is currently
+  // very simplistic as completion (via completion callback or cancellation)
+  // immediately "detaches" any worker threads, so the best we can do is give
+  // them a little time.  If we start running into Valgrind leaks, we can
+  // do something a bit more clever to track worker threads even when the
+  // DhcpProxyScriptFetcherWin state machine has finished.
+  void FinishTestAllowCleanup() {
+    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
+  }
+
+  scoped_ptr<URLRequestContext> context_;
+  scoped_ptr<DhcpProxyScriptFetcherWin> fetcher_;
+  bool finished_;
+  string16 pac_text_;
+  base::OneShotTimer<RealFetchTester> timeout_;
+  base::OneShotTimer<RealFetchTester> cancel_timer_;
+  bool on_completion_is_error_;
+};
+
+TEST(DhcpProxyScriptFetcherWin, RealFetch) {
+  // This tests a call to Fetch() with no stubbing out of dependencies.
+  //
+  // We don't make assumptions about the environment this unit test is
+  // running in, so it just exercises the code to make sure there
+  // is no crash and no unexpected error returned, but does not assert on
+  // results beyond that.
+  RealFetchTester fetcher;
+  fetcher.RunTest();
+
+  fetcher.WaitUntilDone();
+  printf("PAC URL was %s\n",
+      fetcher.fetcher_->GetPacURL().possibly_invalid_spec().c_str());
+
+  fetcher.FinishTestAllowCleanup();
+}
+
+TEST(DhcpProxyScriptFetcherWin, RealFetchWithCancel) {
+  // Does a Fetch() with an immediate cancel.  As before, just
+  // exercises the code without stubbing out dependencies.
+  RealFetchTester fetcher;
+  fetcher.RunTestWithCancel();
+  MessageLoop::current()->RunUntilIdle();
+
+  // Attempt to avoid Valgrind leak reports in case worker thread is
+  // still running.
+  fetcher.FinishTestAllowCleanup();
+}
+
+// For RealFetchWithDeferredCancel, below.
+class DelayingDhcpProxyScriptAdapterFetcher
+    : public DhcpProxyScriptAdapterFetcher {
+ public:
+  explicit DelayingDhcpProxyScriptAdapterFetcher(
+      URLRequestContext* url_request_context)
+      : DhcpProxyScriptAdapterFetcher(url_request_context) {
+  }
+
+  class DelayingDhcpQuery : public DhcpQuery {
+   public:
+    explicit DelayingDhcpQuery()
+        : DhcpQuery() {
+    }
+
+    std::string ImplGetPacURLFromDhcp(
+        const std::string& adapter_name) OVERRIDE {
+      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(20));
+      return DhcpQuery::ImplGetPacURLFromDhcp(adapter_name);
+    }
+  };
+
+  DhcpQuery* ImplCreateDhcpQuery() OVERRIDE {
+    return new DelayingDhcpQuery();
+  }
+};
+
+// For RealFetchWithDeferredCancel, below.
+class DelayingDhcpProxyScriptFetcherWin
+    : public DhcpProxyScriptFetcherWin {
+ public:
+  explicit DelayingDhcpProxyScriptFetcherWin(
+      URLRequestContext* context)
+      : DhcpProxyScriptFetcherWin(context) {
+  }
+
+  DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() OVERRIDE {
+    return new DelayingDhcpProxyScriptAdapterFetcher(url_request_context());
+  }
+};
+
+TEST(DhcpProxyScriptFetcherWin, RealFetchWithDeferredCancel) {
+  // Does a Fetch() with a slightly delayed cancel.  As before, just
+  // exercises the code without stubbing out dependencies, but
+  // introduces a guaranteed 20 ms delay on the worker threads so that
+  // the cancel is called before they complete.
+  RealFetchTester fetcher;
+  fetcher.fetcher_.reset(
+      new DelayingDhcpProxyScriptFetcherWin(fetcher.context_.get()));
+  fetcher.on_completion_is_error_ = true;
+  fetcher.RunTestWithDeferredCancel();
+  fetcher.WaitUntilDone();
+}
+
+// The remaining tests are to exercise our state machine in various
+// situations, with actual network access fully stubbed out.
+
+class DummyDhcpProxyScriptAdapterFetcher
+    : public DhcpProxyScriptAdapterFetcher {
+ public:
+  explicit DummyDhcpProxyScriptAdapterFetcher(URLRequestContext* context)
+      : DhcpProxyScriptAdapterFetcher(context),
+        did_finish_(false),
+        result_(OK),
+        pac_script_(L"bingo"),
+        fetch_delay_ms_(1) {
+  }
+
+  void Fetch(const std::string& adapter_name,
+             const CompletionCallback& callback) OVERRIDE {
+    callback_ = callback;
+    timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(fetch_delay_ms_),
+                 this, &DummyDhcpProxyScriptAdapterFetcher::OnTimer);
+  }
+
+  void Cancel() OVERRIDE {
+    timer_.Stop();
+  }
+
+  bool DidFinish() const OVERRIDE {
+    return did_finish_;
+  }
+
+  int GetResult() const OVERRIDE {
+    return result_;
+  }
+
+  string16 GetPacScript() const OVERRIDE {
+    return pac_script_;
+  }
+
+  void OnTimer() {
+    callback_.Run(result_);
+  }
+
+  void Configure(
+      bool did_finish, int result, string16 pac_script, int fetch_delay_ms) {
+    did_finish_ = did_finish;
+    result_ = result;
+    pac_script_ = pac_script;
+    fetch_delay_ms_ = fetch_delay_ms;
+  }
+
+ private:
+  bool did_finish_;
+  int result_;
+  string16 pac_script_;
+  int fetch_delay_ms_;
+  CompletionCallback callback_;
+  base::OneShotTimer<DummyDhcpProxyScriptAdapterFetcher> timer_;
+};
+
+class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
+ public:
+  class MockAdapterQuery : public AdapterQuery {
+   public:
+    MockAdapterQuery() {
+    }
+
+    virtual ~MockAdapterQuery() {
+    }
+
+    virtual bool ImplGetCandidateAdapterNames(
+        std::set<std::string>* adapter_names) OVERRIDE {
+      adapter_names->insert(
+          mock_adapter_names_.begin(), mock_adapter_names_.end());
+      return true;
+    }
+
+    std::vector<std::string> mock_adapter_names_;
+  };
+
+  MockDhcpProxyScriptFetcherWin(URLRequestContext* context)
+      : DhcpProxyScriptFetcherWin(context),
+        num_fetchers_created_(0),
+        worker_finished_event_(true, false) {
+    ResetTestState();
+  }
+
+  virtual ~MockDhcpProxyScriptFetcherWin() {
+    ResetTestState();
+  }
+
+  // Adds a fetcher object to the queue of fetchers used by
+  // |ImplCreateAdapterFetcher()|, and its name to the list of adapters
+  // returned by ImplGetCandidateAdapterNames.
+  void PushBackAdapter(const std::string& adapter_name,
+                       DhcpProxyScriptAdapterFetcher* fetcher) {
+    adapter_query_->mock_adapter_names_.push_back(adapter_name);
+    adapter_fetchers_.push_back(fetcher);
+  }
+
+  void ConfigureAndPushBackAdapter(const std::string& adapter_name,
+                                   bool did_finish,
+                                   int result,
+                                   string16 pac_script,
+                                   base::TimeDelta fetch_delay) {
+    scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
+        new DummyDhcpProxyScriptAdapterFetcher(url_request_context()));
+    adapter_fetcher->Configure(
+        did_finish, result, pac_script, fetch_delay.InMilliseconds());
+    PushBackAdapter(adapter_name, adapter_fetcher.release());
+  }
+
+  DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() OVERRIDE {
+    ++num_fetchers_created_;
+    return adapter_fetchers_[next_adapter_fetcher_index_++];
+  }
+
+  virtual AdapterQuery* ImplCreateAdapterQuery() OVERRIDE {
+    DCHECK(adapter_query_);
+    return adapter_query_.get();
+  }
+
+  base::TimeDelta ImplGetMaxWait() OVERRIDE {
+    return max_wait_;
+  }
+
+  void ImplOnGetCandidateAdapterNamesDone() OVERRIDE {
+    worker_finished_event_.Signal();
+  }
+
+  void ResetTestState() {
+    // Delete any adapter fetcher objects we didn't hand out.
+    std::vector<DhcpProxyScriptAdapterFetcher*>::const_iterator it
+        = adapter_fetchers_.begin();
+    for (; it != adapter_fetchers_.end(); ++it) {
+      if (num_fetchers_created_-- <= 0) {
+        delete (*it);
+      }
+    }
+
+    next_adapter_fetcher_index_ = 0;
+    num_fetchers_created_ = 0;
+    adapter_fetchers_.clear();
+    adapter_query_ = new MockAdapterQuery();
+    max_wait_ = TestTimeouts::tiny_timeout();
+  }
+
+  bool HasPendingFetchers() {
+    return num_pending_fetchers() > 0;
+  }
+
+  int next_adapter_fetcher_index_;
+
+  // Ownership gets transferred to the implementation class via
+  // ImplCreateAdapterFetcher, but any objects not handed out are
+  // deleted on destruction.
+  std::vector<DhcpProxyScriptAdapterFetcher*> adapter_fetchers_;
+
+  scoped_refptr<MockAdapterQuery> adapter_query_;
+
+  base::TimeDelta max_wait_;
+  int num_fetchers_created_;
+  base::WaitableEvent worker_finished_event_;
+};
+
+class FetcherClient {
+public:
+  FetcherClient()
+      : context_(new TestURLRequestContext),
+        fetcher_(context_.get()),
+        finished_(false),
+        result_(ERR_UNEXPECTED) {
+  }
+
+  void RunTest() {
+    int result = fetcher_.Fetch(
+        &pac_text_,
+        base::Bind(&FetcherClient::OnCompletion, base::Unretained(this)));
+    ASSERT_EQ(ERR_IO_PENDING, result);
+  }
+
+  void RunMessageLoopUntilComplete() {
+    while (!finished_) {
+      MessageLoop::current()->RunUntilIdle();
+    }
+    MessageLoop::current()->RunUntilIdle();
+  }
+
+  void RunMessageLoopUntilWorkerDone() {
+    DCHECK(fetcher_.adapter_query_.get());
+    while (!fetcher_.worker_finished_event_.TimedWait(
+        base::TimeDelta::FromMilliseconds(10))) {
+      MessageLoop::current()->RunUntilIdle();
+    }
+  }
+
+  void OnCompletion(int result) {
+    finished_ = true;
+    result_ = result;
+  }
+
+  void ResetTestState() {
+    finished_ = false;
+    result_ = ERR_UNEXPECTED;
+    pac_text_ = L"";
+    fetcher_.ResetTestState();
+  }
+
+  scoped_ptr<URLRequestContext> context_;
+  MockDhcpProxyScriptFetcherWin fetcher_;
+  bool finished_;
+  int result_;
+  string16 pac_text_;
+};
+
+// We separate out each test's logic so that we can easily implement
+// the ReuseFetcher test at the bottom.
+void TestNormalCaseURLConfiguredOneAdapter(FetcherClient* client) {
+  TestURLRequestContext context;
+  scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
+      new DummyDhcpProxyScriptAdapterFetcher(&context));
+  adapter_fetcher->Configure(true, OK, L"bingo", 1);
+  client->fetcher_.PushBackAdapter("a", adapter_fetcher.release());
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_EQ(OK, client->result_);
+  ASSERT_EQ(L"bingo", client->pac_text_);
+}
+
+TEST(DhcpProxyScriptFetcherWin, NormalCaseURLConfiguredOneAdapter) {
+  FetcherClient client;
+  TestNormalCaseURLConfiguredOneAdapter(&client);
+}
+
+void TestNormalCaseURLConfiguredMultipleAdapters(FetcherClient* client) {
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "second", true, OK, L"bingo", base::TimeDelta::FromMilliseconds(50));
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "third", true, OK, L"rocko", base::TimeDelta::FromMilliseconds(1));
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_EQ(OK, client->result_);
+  ASSERT_EQ(L"bingo", client->pac_text_);
+}
+
+TEST(DhcpProxyScriptFetcherWin, NormalCaseURLConfiguredMultipleAdapters) {
+  FetcherClient client;
+  TestNormalCaseURLConfiguredMultipleAdapters(&client);
+}
+
+void TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout(
+    FetcherClient* client) {
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  // This will time out.
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "second", false, ERR_IO_PENDING, L"bingo",
+      TestTimeouts::action_timeout());
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "third", true, OK, L"rocko", base::TimeDelta::FromMilliseconds(1));
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_EQ(OK, client->result_);
+  ASSERT_EQ(L"rocko", client->pac_text_);
+}
+
+TEST(DhcpProxyScriptFetcherWin,
+     NormalCaseURLConfiguredMultipleAdaptersWithTimeout) {
+  FetcherClient client;
+  TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout(&client);
+}
+
+void TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout(
+    FetcherClient* client) {
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  // This will time out.
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "second", false, ERR_IO_PENDING, L"bingo",
+      TestTimeouts::action_timeout());
+  // This is the first non-ERR_PAC_NOT_IN_DHCP error and as such
+  // should be chosen.
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "third", true, ERR_PAC_STATUS_NOT_OK, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "fourth", true, ERR_NOT_IMPLEMENTED, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_EQ(ERR_PAC_STATUS_NOT_OK, client->result_);
+  ASSERT_EQ(L"", client->pac_text_);
+}
+
+TEST(DhcpProxyScriptFetcherWin,
+     FailureCaseURLConfiguredMultipleAdaptersWithTimeout) {
+  FetcherClient client;
+  TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout(&client);
+}
+
+void TestFailureCaseNoURLConfigured(FetcherClient* client) {
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "most_preferred", true, ERR_PAC_NOT_IN_DHCP, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  // This will time out.
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "second", false, ERR_IO_PENDING, L"bingo",
+      TestTimeouts::action_timeout());
+  // This is the first non-ERR_PAC_NOT_IN_DHCP error and as such
+  // should be chosen.
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "third", true, ERR_PAC_NOT_IN_DHCP, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, client->result_);
+  ASSERT_EQ(L"", client->pac_text_);
+}
+
+TEST(DhcpProxyScriptFetcherWin, FailureCaseNoURLConfigured) {
+  FetcherClient client;
+  TestFailureCaseNoURLConfigured(&client);
+}
+
+void TestFailureCaseNoDhcpAdapters(FetcherClient* client) {
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, client->result_);
+  ASSERT_EQ(L"", client->pac_text_);
+  ASSERT_EQ(0, client->fetcher_.num_fetchers_created_);
+}
+
+TEST(DhcpProxyScriptFetcherWin, FailureCaseNoDhcpAdapters) {
+  FetcherClient client;
+  TestFailureCaseNoDhcpAdapters(&client);
+}
+
+void TestShortCircuitLessPreferredAdapters(FetcherClient* client) {
+  // Here we have a bunch of adapters; the first reports no PAC in DHCP,
+  // the second responds quickly with a PAC file, the rest take a long
+  // time.  Verify that we complete quickly and do not wait for the slow
+  // adapters, i.e. we finish before timeout.
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "1", true, ERR_PAC_NOT_IN_DHCP, L"",
+      base::TimeDelta::FromMilliseconds(1));
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "2", true, OK, L"bingo",
+      base::TimeDelta::FromMilliseconds(1));
+  client->fetcher_.ConfigureAndPushBackAdapter(
+      "3", true, OK, L"wrongo", TestTimeouts::action_max_timeout());
+
+  // Increase the timeout to ensure the short circuit mechanism has
+  // time to kick in before the timeout waiting for more adapters kicks in.
+  client->fetcher_.max_wait_ = TestTimeouts::action_timeout();
+
+  PerfTimer timer;
+  client->RunTest();
+  client->RunMessageLoopUntilComplete();
+  ASSERT_TRUE(client->fetcher_.HasPendingFetchers());
+  // Assert that the time passed is definitely less than the wait timer
+  // timeout, to get a second signal that it was the shortcut mechanism
+  // (in OnFetcherDone) that kicked in, and not the timeout waiting for
+  // more adapters.
+  ASSERT_GT(client->fetcher_.max_wait_ - (client->fetcher_.max_wait_ / 10),
+            timer.Elapsed());
+}
+
+TEST(DhcpProxyScriptFetcherWin, ShortCircuitLessPreferredAdapters) {
+  FetcherClient client;
+  TestShortCircuitLessPreferredAdapters(&client);
+}
+
+void TestImmediateCancel(FetcherClient* client) {
+  TestURLRequestContext context;
+  scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
+      new DummyDhcpProxyScriptAdapterFetcher(&context));
+  adapter_fetcher->Configure(true, OK, L"bingo", 1);
+  client->fetcher_.PushBackAdapter("a", adapter_fetcher.release());
+  client->RunTest();
+  client->fetcher_.Cancel();
+  client->RunMessageLoopUntilWorkerDone();
+  ASSERT_EQ(0, client->fetcher_.num_fetchers_created_);
+}
+
+// Regression test to check that when we cancel immediately, no
+// adapter fetchers get created.
+TEST(DhcpProxyScriptFetcherWin, ImmediateCancel) {
+  FetcherClient client;
+  TestImmediateCancel(&client);
+}
+
+TEST(DhcpProxyScriptFetcherWin, ReuseFetcher) {
+  FetcherClient client;
+
+  // The ProxyScriptFetcher interface stipulates that only a single
+  // |Fetch()| may be in flight at once, but allows reuse, so test
+  // that the state transitions correctly from done to start in all
+  // cases we're testing.
+
+  typedef void (*FetcherClientTestFunction)(FetcherClient*);
+  typedef std::vector<FetcherClientTestFunction> TestVector;
+  TestVector test_functions;
+  test_functions.push_back(TestNormalCaseURLConfiguredOneAdapter);
+  test_functions.push_back(TestNormalCaseURLConfiguredMultipleAdapters);
+  test_functions.push_back(
+      TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout);
+  test_functions.push_back(
+      TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout);
+  test_functions.push_back(TestFailureCaseNoURLConfigured);
+  test_functions.push_back(TestFailureCaseNoDhcpAdapters);
+  test_functions.push_back(TestShortCircuitLessPreferredAdapters);
+  test_functions.push_back(TestImmediateCancel);
+
+  std::random_shuffle(test_functions.begin(),
+                      test_functions.end(),
+                      base::RandGenerator);
+  for (TestVector::const_iterator it = test_functions.begin();
+       it != test_functions.end();
+       ++it) {
+    (*it)(&client);
+    client.ResetTestState();
+  }
+
+  // Re-do the first test to make sure the last test that was run did
+  // not leave things in a bad state.
+  (*test_functions.begin())(&client);
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/src/net/proxy/dhcpcsvc_init_win.cc b/src/net/proxy/dhcpcsvc_init_win.cc
new file mode 100644
index 0000000..7e32aea
--- /dev/null
+++ b/src/net/proxy/dhcpcsvc_init_win.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/dhcpcsvc_init_win.h"
+
+#include "base/lazy_instance.h"
+#include "base/logging.h"
+
+#include <dhcpcsdk.h>
+#include <dhcpv6csdk.h>
+
+namespace {
+
+class DhcpcsvcInitSingleton {
+ public:
+  DhcpcsvcInitSingleton() {
+    DWORD version = 0;
+    DWORD err = DhcpCApiInitialize(&version);
+    DCHECK(err == ERROR_SUCCESS);  // DCHECK_EQ complains of unsigned mismatch.
+  }
+
+  ~DhcpcsvcInitSingleton() {
+    // Worker pool threads that use the DHCP API may still be running, so skip
+    // cleanup.
+  }
+};
+
+static base::LazyInstance<DhcpcsvcInitSingleton> g_dhcpcsvc_init_singleton =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+namespace net {
+
+void EnsureDhcpcsvcInit() {
+  g_dhcpcsvc_init_singleton.Get();
+}
+
+}  // namespace net
diff --git a/src/net/proxy/dhcpcsvc_init_win.h b/src/net/proxy/dhcpcsvc_init_win.h
new file mode 100644
index 0000000..39bdf24
--- /dev/null
+++ b/src/net/proxy/dhcpcsvc_init_win.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_DHCPCSVC_INIT_WIN_H
+#define NET_PROXY_DHCPCSVC_INIT_WIN_H
+
+namespace net {
+
+// Initialization of the Dhcpcsvc library must happen before any of its
+// calls are made.  This function will make sure that the appropriate
+// initialization has been done, and that uninitialization is also
+// performed at static uninitialization time.
+//
+// Note: This initializes only for DHCP, not DHCPv6.
+void EnsureDhcpcsvcInit();
+
+}  // namespace net
+
+#endif  // NET_PROXY_DHCPCSVC_INIT_WIN_H
diff --git a/src/net/proxy/mock_proxy_resolver.cc b/src/net/proxy/mock_proxy_resolver.cc
new file mode 100644
index 0000000..a7fe409
--- /dev/null
+++ b/src/net/proxy/mock_proxy_resolver.cc
@@ -0,0 +1,123 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/mock_proxy_resolver.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+
+namespace net {
+
+MockAsyncProxyResolverBase::Request::Request(
+    MockAsyncProxyResolverBase* resolver, const GURL& url, ProxyInfo* results,
+    const CompletionCallback& callback)
+        : resolver_(resolver),
+          url_(url),
+          results_(results),
+          callback_(callback),
+          origin_loop_(MessageLoop::current()) {
+    }
+
+    void MockAsyncProxyResolverBase::Request::CompleteNow(int rv) {
+      CompletionCallback callback = callback_;
+
+      // May delete |this|.
+      resolver_->RemovePendingRequest(this);
+
+      callback.Run(rv);
+    }
+
+MockAsyncProxyResolverBase::Request::~Request() {}
+
+
+MockAsyncProxyResolverBase::SetPacScriptRequest::SetPacScriptRequest(
+        MockAsyncProxyResolverBase* resolver,
+        const scoped_refptr<ProxyResolverScriptData>& script_data,
+        const CompletionCallback& callback)
+        : resolver_(resolver),
+          script_data_(script_data),
+          callback_(callback),
+          origin_loop_(MessageLoop::current()) {
+    }
+
+MockAsyncProxyResolverBase::SetPacScriptRequest::~SetPacScriptRequest() {}
+
+    void MockAsyncProxyResolverBase::SetPacScriptRequest::CompleteNow(int rv) {
+       CompletionCallback callback = callback_;
+
+      // Will delete |this|.
+      resolver_->RemovePendingSetPacScriptRequest(this);
+
+      callback.Run(rv);
+    }
+
+MockAsyncProxyResolverBase::~MockAsyncProxyResolverBase() {}
+
+int MockAsyncProxyResolverBase::GetProxyForURL(
+    const GURL& url, ProxyInfo* results, const CompletionCallback& callback,
+    RequestHandle* request_handle, const BoundNetLog& /*net_log*/) {
+  scoped_refptr<Request> request = new Request(this, url, results, callback);
+  pending_requests_.push_back(request);
+
+  if (request_handle)
+    *request_handle = reinterpret_cast<RequestHandle>(request.get());
+
+  // Test code completes the request by calling request->CompleteNow().
+  return ERR_IO_PENDING;
+}
+
+void MockAsyncProxyResolverBase::CancelRequest(RequestHandle request_handle) {
+  scoped_refptr<Request> request = reinterpret_cast<Request*>(request_handle);
+  cancelled_requests_.push_back(request);
+  RemovePendingRequest(request);
+}
+
+LoadState MockAsyncProxyResolverBase::GetLoadState(
+    RequestHandle request_handle) const {
+  NOTREACHED();
+  return LOAD_STATE_IDLE;
+}
+
+LoadState MockAsyncProxyResolverBase::GetLoadStateThreadSafe(
+    RequestHandle request_handle) const {
+  NOTREACHED();
+  return LOAD_STATE_IDLE;
+}
+
+int MockAsyncProxyResolverBase::SetPacScript(
+    const scoped_refptr<ProxyResolverScriptData>& script_data,
+    const CompletionCallback& callback) {
+  DCHECK(!pending_set_pac_script_request_.get());
+  pending_set_pac_script_request_.reset(
+      new SetPacScriptRequest(this, script_data, callback));
+  // Finished when user calls SetPacScriptRequest::CompleteNow().
+  return ERR_IO_PENDING;
+}
+
+void MockAsyncProxyResolverBase::CancelSetPacScript() {
+  // Do nothing (caller was responsible for completing the request).
+}
+
+MockAsyncProxyResolverBase::SetPacScriptRequest*
+MockAsyncProxyResolverBase::pending_set_pac_script_request() const {
+  return pending_set_pac_script_request_.get();
+}
+
+void MockAsyncProxyResolverBase::RemovePendingRequest(Request* request) {
+  RequestsList::iterator it = std::find(
+      pending_requests_.begin(), pending_requests_.end(), request);
+  DCHECK(it != pending_requests_.end());
+  pending_requests_.erase(it);
+}
+
+void MockAsyncProxyResolverBase::RemovePendingSetPacScriptRequest(
+    SetPacScriptRequest* request) {
+  DCHECK_EQ(request, pending_set_pac_script_request());
+  pending_set_pac_script_request_.reset();
+}
+
+MockAsyncProxyResolverBase::MockAsyncProxyResolverBase(bool expects_pac_bytes)
+    : ProxyResolver(expects_pac_bytes) {}
+
+}  // namespace net
diff --git a/src/net/proxy/mock_proxy_resolver.h b/src/net/proxy/mock_proxy_resolver.h
new file mode 100644
index 0000000..e68e42b
--- /dev/null
+++ b/src/net/proxy/mock_proxy_resolver.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_MOCK_PROXY_RESOLVER_H_
+#define NET_PROXY_MOCK_PROXY_RESOLVER_H_
+
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_resolver.h"
+
+class MessageLoop;
+
+namespace net {
+
+// Asynchronous mock proxy resolver. All requests complete asynchronously,
+// user must call Request::CompleteNow() on a pending request to signal it.
+class MockAsyncProxyResolverBase : public ProxyResolver {
+ public:
+  class Request : public base::RefCounted<Request> {
+   public:
+    Request(MockAsyncProxyResolverBase* resolver,
+            const GURL& url,
+            ProxyInfo* results,
+            const net::CompletionCallback& callback);
+
+    const GURL& url() const { return url_; }
+    ProxyInfo* results() const { return results_; }
+    const net::CompletionCallback& callback() const { return callback_; }
+
+    void CompleteNow(int rv);
+
+   private:
+    friend class base::RefCounted<Request>;
+
+    virtual ~Request();
+
+    MockAsyncProxyResolverBase* resolver_;
+    const GURL url_;
+    ProxyInfo* results_;
+    net::CompletionCallback callback_;
+    MessageLoop* origin_loop_;
+  };
+
+  class SetPacScriptRequest {
+   public:
+    SetPacScriptRequest(
+        MockAsyncProxyResolverBase* resolver,
+        const scoped_refptr<ProxyResolverScriptData>& script_data,
+        const net::CompletionCallback& callback);
+    ~SetPacScriptRequest();
+
+    const ProxyResolverScriptData* script_data() const { return script_data_; }
+
+    void CompleteNow(int rv);
+
+   private:
+    MockAsyncProxyResolverBase* resolver_;
+    const scoped_refptr<ProxyResolverScriptData> script_data_;
+    net::CompletionCallback callback_;
+    MessageLoop* origin_loop_;
+  };
+
+  typedef std::vector<scoped_refptr<Request> > RequestsList;
+
+  virtual ~MockAsyncProxyResolverBase();
+
+  // ProxyResolver implementation.
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const net::CompletionCallback& callback,
+                             RequestHandle* request_handle,
+                             const BoundNetLog& /*net_log*/) OVERRIDE;
+  virtual void CancelRequest(RequestHandle request_handle) OVERRIDE;
+  virtual LoadState GetLoadState(RequestHandle request_handle) const OVERRIDE;
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request_handle) const OVERRIDE;
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const net::CompletionCallback& callback) OVERRIDE;
+  virtual void CancelSetPacScript() OVERRIDE;
+
+  const RequestsList& pending_requests() const {
+    return pending_requests_;
+  }
+
+  const RequestsList& cancelled_requests() const {
+    return cancelled_requests_;
+  }
+
+  SetPacScriptRequest* pending_set_pac_script_request() const;
+
+  bool has_pending_set_pac_script_request() const {
+    return pending_set_pac_script_request_.get() != NULL;
+  }
+
+  void RemovePendingRequest(Request* request);
+
+  void RemovePendingSetPacScriptRequest(SetPacScriptRequest* request);
+
+ protected:
+  explicit MockAsyncProxyResolverBase(bool expects_pac_bytes);
+
+ private:
+  RequestsList pending_requests_;
+  RequestsList cancelled_requests_;
+  scoped_ptr<SetPacScriptRequest> pending_set_pac_script_request_;
+};
+
+class MockAsyncProxyResolver : public MockAsyncProxyResolverBase {
+ public:
+  MockAsyncProxyResolver()
+      : MockAsyncProxyResolverBase(false /*expects_pac_bytes*/) {}
+};
+
+class MockAsyncProxyResolverExpectsBytes : public MockAsyncProxyResolverBase {
+ public:
+  MockAsyncProxyResolverExpectsBytes()
+      : MockAsyncProxyResolverBase(true /*expects_pac_bytes*/) {}
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_MOCK_PROXY_RESOLVER_H_
diff --git a/src/net/proxy/mock_proxy_script_fetcher.cc b/src/net/proxy/mock_proxy_script_fetcher.cc
new file mode 100644
index 0000000..c190aa2
--- /dev/null
+++ b/src/net/proxy/mock_proxy_script_fetcher.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/mock_proxy_script_fetcher.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/string16.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/net_errors.h"
+
+namespace net {
+
+MockProxyScriptFetcher::MockProxyScriptFetcher()
+    : pending_request_text_(NULL),
+      waiting_for_fetch_(false) {
+}
+
+MockProxyScriptFetcher::~MockProxyScriptFetcher() {}
+
+// ProxyScriptFetcher implementation.
+int MockProxyScriptFetcher::Fetch(const GURL& url, string16* text,
+                                  const CompletionCallback& callback) {
+  DCHECK(!has_pending_request());
+
+  // Save the caller's information, and have them wait.
+  pending_request_url_ = url;
+  pending_request_callback_ = callback;
+  pending_request_text_ = text;
+
+  if (waiting_for_fetch_)
+    MessageLoop::current()->Quit();
+
+  return ERR_IO_PENDING;
+}
+
+void MockProxyScriptFetcher::NotifyFetchCompletion(
+    int result, const std::string& ascii_text) {
+  DCHECK(has_pending_request());
+  *pending_request_text_ = ASCIIToUTF16(ascii_text);
+  CompletionCallback callback = pending_request_callback_;
+  pending_request_callback_.Reset();
+  callback.Run(result);
+}
+
+void MockProxyScriptFetcher::Cancel() {
+}
+
+URLRequestContext* MockProxyScriptFetcher::GetRequestContext() const {
+  return NULL;
+}
+
+const GURL& MockProxyScriptFetcher::pending_request_url() const {
+  return pending_request_url_;
+}
+
+bool MockProxyScriptFetcher::has_pending_request() const {
+  return !pending_request_callback_.is_null();
+}
+
+void MockProxyScriptFetcher::WaitUntilFetch() {
+  DCHECK(!has_pending_request());
+  waiting_for_fetch_ = true;
+  MessageLoop::current()->Run();
+  waiting_for_fetch_ = false;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/mock_proxy_script_fetcher.h b/src/net/proxy/mock_proxy_script_fetcher.h
new file mode 100644
index 0000000..12b963f
--- /dev/null
+++ b/src/net/proxy/mock_proxy_script_fetcher.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_MOCK_PROXY_SCRIPT_FETCHER_H_
+#define NET_PROXY_MOCK_PROXY_SCRIPT_FETCHER_H_
+
+#include "base/compiler_specific.h"
+#include "googleurl/src/gurl.h"
+#include "net/proxy/proxy_script_fetcher.h"
+
+#include <string>
+
+namespace net {
+
+class URLRequestContext;
+
+// A mock ProxyScriptFetcher. No result will be returned to the fetch client
+// until we call NotifyFetchCompletion() to set the results.
+class MockProxyScriptFetcher : public ProxyScriptFetcher {
+ public:
+  MockProxyScriptFetcher();
+  virtual ~MockProxyScriptFetcher();
+
+  // ProxyScriptFetcher implementation.
+  virtual int Fetch(const GURL& url,
+                    string16* text,
+                    const CompletionCallback& callback) OVERRIDE;
+  virtual void Cancel() OVERRIDE;
+  virtual URLRequestContext* GetRequestContext() const OVERRIDE;
+
+  void NotifyFetchCompletion(int result, const std::string& ascii_text);
+  const GURL& pending_request_url() const;
+  bool has_pending_request() const;
+
+  // Spins the message loop until this->Fetch() is invoked.
+  void WaitUntilFetch();
+
+ private:
+  GURL pending_request_url_;
+  CompletionCallback pending_request_callback_;
+  string16* pending_request_text_;
+  bool waiting_for_fetch_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_MOCK_PROXY_SCRIPT_FETCHER_H_
diff --git a/src/net/proxy/multi_threaded_proxy_resolver.cc b/src/net/proxy/multi_threaded_proxy_resolver.cc
new file mode 100644
index 0000000..bd9890c
--- /dev/null
+++ b/src/net/proxy/multi_threaded_proxy_resolver.cc
@@ -0,0 +1,611 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/multi_threaded_proxy_resolver.h"
+
+#include "base/bind.h"
+#include "base/message_loop_proxy.h"
+#include "base/metrics/histogram.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_restrictions.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/proxy/proxy_info.h"
+
+// TODO(eroman): Have the MultiThreadedProxyResolver clear its PAC script
+//               data when SetPacScript fails. That will reclaim memory when
+//               testing bogus scripts.
+
+namespace net {
+
+namespace {
+
+class PurgeMemoryTask : public base::RefCountedThreadSafe<PurgeMemoryTask> {
+ public:
+  explicit PurgeMemoryTask(ProxyResolver* resolver) : resolver_(resolver) {}
+  void PurgeMemory() { resolver_->PurgeMemory(); }
+ private:
+  friend class base::RefCountedThreadSafe<PurgeMemoryTask>;
+  ~PurgeMemoryTask() {}
+  ProxyResolver* resolver_;
+};
+
+}  // namespace
+
+// An "executor" is a job-runner for PAC requests. It encapsulates a worker
+// thread and a synchronous ProxyResolver (which will be operated on said
+// thread.)
+class MultiThreadedProxyResolver::Executor
+    : public base::RefCountedThreadSafe<MultiThreadedProxyResolver::Executor > {
+ public:
+  // |coordinator| must remain valid throughout our lifetime. It is used to
+  // signal when the executor is ready to receive work by calling
+  // |coordinator->OnExecutorReady()|.
+  // The constructor takes ownership of |resolver|.
+  // |thread_number| is an identifier used when naming the worker thread.
+  Executor(MultiThreadedProxyResolver* coordinator,
+           ProxyResolver* resolver,
+           int thread_number);
+
+  // Submit a job to this executor.
+  void StartJob(Job* job);
+
+  // Callback for when a job has completed running on the executor's thread.
+  void OnJobCompleted(Job* job);
+
+  // Cleanup the executor. Cancels all outstanding work, and frees the thread
+  // and resolver.
+  void Destroy();
+
+  void PurgeMemory();
+
+  // Returns the outstanding job, or NULL.
+  Job* outstanding_job() const { return outstanding_job_.get(); }
+
+  ProxyResolver* resolver() { return resolver_.get(); }
+
+  int thread_number() const { return thread_number_; }
+
+ private:
+  friend class base::RefCountedThreadSafe<Executor>;
+  ~Executor();
+
+  MultiThreadedProxyResolver* coordinator_;
+  const int thread_number_;
+
+  // The currently active job for this executor (either a SetPacScript or
+  // GetProxyForURL task).
+  scoped_refptr<Job> outstanding_job_;
+
+  // The synchronous resolver implementation.
+  scoped_ptr<ProxyResolver> resolver_;
+
+  // The thread where |resolver_| is run on.
+  // Note that declaration ordering is important here. |thread_| needs to be
+  // destroyed *before* |resolver_|, in case |resolver_| is currently
+  // executing on |thread_|.
+  scoped_ptr<base::Thread> thread_;
+};
+
+// MultiThreadedProxyResolver::Job ---------------------------------------------
+
+class MultiThreadedProxyResolver::Job
+    : public base::RefCountedThreadSafe<MultiThreadedProxyResolver::Job> {
+ public:
+  // Identifies the subclass of Job (only being used for debugging purposes).
+  enum Type {
+    TYPE_GET_PROXY_FOR_URL,
+    TYPE_SET_PAC_SCRIPT,
+    TYPE_SET_PAC_SCRIPT_INTERNAL,
+  };
+
+  Job(Type type, const CompletionCallback& callback)
+      : type_(type),
+        callback_(callback),
+        executor_(NULL),
+        was_cancelled_(false) {
+  }
+
+  void set_executor(Executor* executor) {
+    executor_ = executor;
+  }
+
+  // The "executor" is the job runner that is scheduling this job. If
+  // this job has not been submitted to an executor yet, this will be
+  // NULL (and we know it hasn't started yet).
+  Executor* executor() {
+    return executor_;
+  }
+
+  // Mark the job as having been cancelled.
+  void Cancel() {
+    was_cancelled_ = true;
+  }
+
+  // Returns true if Cancel() has been called.
+  bool was_cancelled() const { return was_cancelled_; }
+
+  Type type() const { return type_; }
+
+  // Returns true if this job still has a user callback. Some jobs
+  // do not have a user callback, because they were helper jobs
+  // scheduled internally (for example TYPE_SET_PAC_SCRIPT_INTERNAL).
+  //
+  // Otherwise jobs that correspond with user-initiated work will
+  // have a non-null callback up until the callback is run.
+  bool has_user_callback() const { return !callback_.is_null(); }
+
+  // This method is called when the job is inserted into a wait queue
+  // because no executors were ready to accept it.
+  virtual void WaitingForThread() {}
+
+  // This method is called just before the job is posted to the work thread.
+  virtual void FinishedWaitingForThread() {}
+
+  // This method is called on the worker thread to do the job's work. On
+  // completion, implementors are expected to call OnJobCompleted() on
+  // |origin_loop|.
+  virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) = 0;
+
+ protected:
+  void OnJobCompleted() {
+    // |executor_| will be NULL if the executor has already been deleted.
+    if (executor_)
+      executor_->OnJobCompleted(this);
+  }
+
+  void RunUserCallback(int result) {
+    DCHECK(has_user_callback());
+    CompletionCallback callback = callback_;
+    // Reset the callback so has_user_callback() will now return false.
+    callback_.Reset();
+    callback.Run(result);
+  }
+
+  friend class base::RefCountedThreadSafe<MultiThreadedProxyResolver::Job>;
+
+  virtual ~Job() {}
+
+ private:
+  const Type type_;
+  CompletionCallback callback_;
+  Executor* executor_;
+  bool was_cancelled_;
+};
+
+// MultiThreadedProxyResolver::SetPacScriptJob ---------------------------------
+
+// Runs on the worker thread to call ProxyResolver::SetPacScript.
+class MultiThreadedProxyResolver::SetPacScriptJob
+    : public MultiThreadedProxyResolver::Job {
+ public:
+  SetPacScriptJob(const scoped_refptr<ProxyResolverScriptData>& script_data,
+                  const CompletionCallback& callback)
+    : Job(!callback.is_null() ? TYPE_SET_PAC_SCRIPT :
+                                TYPE_SET_PAC_SCRIPT_INTERNAL,
+          callback),
+      script_data_(script_data) {
+  }
+
+  // Runs on the worker thread.
+  virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE {
+    ProxyResolver* resolver = executor()->resolver();
+    int rv = resolver->SetPacScript(script_data_, CompletionCallback());
+
+    DCHECK_NE(rv, ERR_IO_PENDING);
+    origin_loop->PostTask(
+        FROM_HERE,
+        base::Bind(&SetPacScriptJob::RequestComplete, this, rv));
+  }
+
+ protected:
+  virtual ~SetPacScriptJob() {}
+
+ private:
+  // Runs the completion callback on the origin thread.
+  void RequestComplete(int result_code) {
+    // The task may have been cancelled after it was started.
+    if (!was_cancelled() && has_user_callback()) {
+      RunUserCallback(result_code);
+    }
+    OnJobCompleted();
+  }
+
+  const scoped_refptr<ProxyResolverScriptData> script_data_;
+};
+
+// MultiThreadedProxyResolver::GetProxyForURLJob ------------------------------
+
+class MultiThreadedProxyResolver::GetProxyForURLJob
+    : public MultiThreadedProxyResolver::Job {
+ public:
+  // |url|         -- the URL of the query.
+  // |results|     -- the structure to fill with proxy resolve results.
+  GetProxyForURLJob(const GURL& url,
+                    ProxyInfo* results,
+                    const CompletionCallback& callback,
+                    const BoundNetLog& net_log)
+      : Job(TYPE_GET_PROXY_FOR_URL, callback),
+        results_(results),
+        net_log_(net_log),
+        url_(url),
+        was_waiting_for_thread_(false) {
+    DCHECK(!callback.is_null());
+    start_time_ = base::TimeTicks::Now();
+  }
+
+  BoundNetLog* net_log() { return &net_log_; }
+
+  virtual void WaitingForThread() OVERRIDE {
+    was_waiting_for_thread_ = true;
+    net_log_.BeginEvent(NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD);
+  }
+
+  virtual void FinishedWaitingForThread() OVERRIDE {
+    DCHECK(executor());
+
+    submitted_to_thread_time_ = base::TimeTicks::Now();
+
+    if (was_waiting_for_thread_) {
+      net_log_.EndEvent(NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD);
+    }
+
+    net_log_.AddEvent(
+        NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD,
+        NetLog::IntegerCallback("thread_number", executor()->thread_number()));
+  }
+
+  // Runs on the worker thread.
+  virtual void Run(scoped_refptr<base::MessageLoopProxy> origin_loop) OVERRIDE {
+    ProxyResolver* resolver = executor()->resolver();
+    int rv = resolver->GetProxyForURL(
+        url_, &results_buf_, CompletionCallback(), NULL, net_log_);
+    DCHECK_NE(rv, ERR_IO_PENDING);
+
+    origin_loop->PostTask(
+        FROM_HERE,
+        base::Bind(&GetProxyForURLJob::QueryComplete, this, rv));
+  }
+
+ protected:
+  virtual ~GetProxyForURLJob() {}
+
+ private:
+  // Runs the completion callback on the origin thread.
+  void QueryComplete(int result_code) {
+    // The Job may have been cancelled after it was started.
+    if (!was_cancelled()) {
+      RecordPerformanceMetrics();
+      if (result_code >= OK) {  // Note: unit-tests use values > 0.
+        results_->Use(results_buf_);
+      }
+      RunUserCallback(result_code);
+    }
+    OnJobCompleted();
+  }
+
+  void RecordPerformanceMetrics() {
+    DCHECK(!was_cancelled());
+
+    base::TimeTicks now = base::TimeTicks::Now();
+
+    // Log the total time the request took to complete.
+    UMA_HISTOGRAM_MEDIUM_TIMES("Net.MTPR_GetProxyForUrl_Time",
+                               now - start_time_);
+
+    // Log the time the request was stalled waiting for a thread to free up.
+    UMA_HISTOGRAM_MEDIUM_TIMES("Net.MTPR_GetProxyForUrl_Thread_Wait_Time",
+                               submitted_to_thread_time_ - start_time_);
+  }
+
+  // Must only be used on the "origin" thread.
+  ProxyInfo* results_;
+
+  // Can be used on either "origin" or worker thread.
+  BoundNetLog net_log_;
+  const GURL url_;
+
+  // Usable from within DoQuery on the worker thread.
+  ProxyInfo results_buf_;
+
+  base::TimeTicks start_time_;
+  base::TimeTicks submitted_to_thread_time_;
+
+  bool was_waiting_for_thread_;
+};
+
+// MultiThreadedProxyResolver::Executor ----------------------------------------
+
+MultiThreadedProxyResolver::Executor::Executor(
+    MultiThreadedProxyResolver* coordinator,
+    ProxyResolver* resolver,
+    int thread_number)
+    : coordinator_(coordinator),
+      thread_number_(thread_number),
+      resolver_(resolver) {
+  DCHECK(coordinator);
+  DCHECK(resolver);
+  // Start up the thread.
+  // Note that it is safe to pass a temporary C-String to Thread(), as it will
+  // make a copy.
+  std::string thread_name =
+      base::StringPrintf("PAC thread #%d", thread_number);
+  thread_.reset(new base::Thread(thread_name.c_str()));
+  CHECK(thread_->Start());
+}
+
+void MultiThreadedProxyResolver::Executor::StartJob(Job* job) {
+  DCHECK(!outstanding_job_);
+  outstanding_job_ = job;
+
+  // Run the job. Once it has completed (regardless of whether it was
+  // cancelled), it will invoke OnJobCompleted() on this thread.
+  job->set_executor(this);
+  job->FinishedWaitingForThread();
+  thread_->message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&Job::Run, job, base::MessageLoopProxy::current()));
+}
+
+void MultiThreadedProxyResolver::Executor::OnJobCompleted(Job* job) {
+  DCHECK_EQ(job, outstanding_job_.get());
+  outstanding_job_ = NULL;
+  coordinator_->OnExecutorReady(this);
+}
+
+void MultiThreadedProxyResolver::Executor::Destroy() {
+  DCHECK(coordinator_);
+
+  // Give the resolver an opportunity to shutdown from THIS THREAD before
+  // joining on the resolver thread. This allows certain implementations
+  // to avoid deadlocks.
+  resolver_->Shutdown();
+
+  {
+    // See http://crbug.com/69710.
+    base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+    // Join the worker thread.
+    thread_.reset();
+  }
+
+  // Cancel any outstanding job.
+  if (outstanding_job_) {
+    outstanding_job_->Cancel();
+    // Orphan the job (since this executor may be deleted soon).
+    outstanding_job_->set_executor(NULL);
+  }
+
+  // It is now safe to free the ProxyResolver, since all the tasks that
+  // were using it on the resolver thread have completed.
+  resolver_.reset();
+
+  // Null some stuff as a precaution.
+  coordinator_ = NULL;
+  outstanding_job_ = NULL;
+}
+
+void MultiThreadedProxyResolver::Executor::PurgeMemory() {
+  scoped_refptr<PurgeMemoryTask> helper(new PurgeMemoryTask(resolver_.get()));
+  thread_->message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&PurgeMemoryTask::PurgeMemory, helper.get()));
+}
+
+MultiThreadedProxyResolver::Executor::~Executor() {
+  // The important cleanup happens as part of Destroy(), which should always be
+  // called first.
+  DCHECK(!coordinator_) << "Destroy() was not called";
+  DCHECK(!thread_.get());
+  DCHECK(!resolver_.get());
+  DCHECK(!outstanding_job_);
+}
+
+// MultiThreadedProxyResolver --------------------------------------------------
+
+MultiThreadedProxyResolver::MultiThreadedProxyResolver(
+    ProxyResolverFactory* resolver_factory,
+    size_t max_num_threads)
+    : ProxyResolver(resolver_factory->resolvers_expect_pac_bytes()),
+      resolver_factory_(resolver_factory),
+      max_num_threads_(max_num_threads) {
+  DCHECK_GE(max_num_threads, 1u);
+}
+
+MultiThreadedProxyResolver::~MultiThreadedProxyResolver() {
+  // We will cancel all outstanding requests.
+  pending_jobs_.clear();
+  ReleaseAllExecutors();
+}
+
+int MultiThreadedProxyResolver::GetProxyForURL(
+    const GURL& url, ProxyInfo* results, const CompletionCallback& callback,
+    RequestHandle* request, const BoundNetLog& net_log) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(!callback.is_null());
+  DCHECK(current_script_data_.get())
+      << "Resolver is un-initialized. Must call SetPacScript() first!";
+
+  scoped_refptr<GetProxyForURLJob> job(
+      new GetProxyForURLJob(url, results, callback, net_log));
+
+  // Completion will be notified through |callback|, unless the caller cancels
+  // the request using |request|.
+  if (request)
+    *request = reinterpret_cast<RequestHandle>(job.get());
+
+  // If there is an executor that is ready to run this request, submit it!
+  Executor* executor = FindIdleExecutor();
+  if (executor) {
+    DCHECK_EQ(0u, pending_jobs_.size());
+    executor->StartJob(job);
+    return ERR_IO_PENDING;
+  }
+
+  // Otherwise queue this request. (We will schedule it to a thread once one
+  // becomes available).
+  job->WaitingForThread();
+  pending_jobs_.push_back(job);
+
+  // If we haven't already reached the thread limit, provision a new thread to
+  // drain the requests more quickly.
+  if (executors_.size() < max_num_threads_) {
+    executor = AddNewExecutor();
+    executor->StartJob(
+        new SetPacScriptJob(current_script_data_, CompletionCallback()));
+  }
+
+  return ERR_IO_PENDING;
+}
+
+void MultiThreadedProxyResolver::CancelRequest(RequestHandle req) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(req);
+
+  Job* job = reinterpret_cast<Job*>(req);
+  DCHECK_EQ(Job::TYPE_GET_PROXY_FOR_URL, job->type());
+
+  if (job->executor()) {
+    // If the job was already submitted to the executor, just mark it
+    // as cancelled so the user callback isn't run on completion.
+    job->Cancel();
+  } else {
+    // Otherwise the job is just sitting in a queue.
+    PendingJobsQueue::iterator it =
+        std::find(pending_jobs_.begin(), pending_jobs_.end(), job);
+    DCHECK(it != pending_jobs_.end());
+    pending_jobs_.erase(it);
+  }
+}
+
+LoadState MultiThreadedProxyResolver::GetLoadState(RequestHandle req) const {
+  DCHECK(CalledOnValidThread());
+  DCHECK(req);
+
+  Job* job = reinterpret_cast<Job*>(req);
+  if (job->executor())
+    return job->executor()->resolver()->GetLoadStateThreadSafe(NULL);
+  return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
+}
+
+LoadState MultiThreadedProxyResolver::GetLoadStateThreadSafe(
+    RequestHandle req) const {
+  NOTIMPLEMENTED();
+  return LOAD_STATE_IDLE;
+}
+
+void MultiThreadedProxyResolver::CancelSetPacScript() {
+  DCHECK(CalledOnValidThread());
+  DCHECK_EQ(0u, pending_jobs_.size());
+  DCHECK_EQ(1u, executors_.size());
+  DCHECK_EQ(Job::TYPE_SET_PAC_SCRIPT,
+            executors_[0]->outstanding_job()->type());
+
+  // Defensively clear some data which shouldn't be getting used
+  // anymore.
+  current_script_data_ = NULL;
+
+  ReleaseAllExecutors();
+}
+
+void MultiThreadedProxyResolver::PurgeMemory() {
+  DCHECK(CalledOnValidThread());
+  for (ExecutorList::iterator it = executors_.begin();
+       it != executors_.end(); ++it) {
+    Executor* executor = *it;
+    executor->PurgeMemory();
+  }
+}
+
+int MultiThreadedProxyResolver::SetPacScript(
+    const scoped_refptr<ProxyResolverScriptData>& script_data,
+    const CompletionCallback&callback) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(!callback.is_null());
+
+  // Save the script details, so we can provision new executors later.
+  current_script_data_ = script_data;
+
+  // The user should not have any outstanding requests when they call
+  // SetPacScript().
+  CheckNoOutstandingUserRequests();
+
+  // Destroy all of the current threads and their proxy resolvers.
+  ReleaseAllExecutors();
+
+  // Provision a new executor, and run the SetPacScript request. On completion
+  // notification will be sent through |callback|.
+  Executor* executor = AddNewExecutor();
+  executor->StartJob(new SetPacScriptJob(script_data, callback));
+  return ERR_IO_PENDING;
+}
+
+void MultiThreadedProxyResolver::CheckNoOutstandingUserRequests() const {
+  DCHECK(CalledOnValidThread());
+  CHECK_EQ(0u, pending_jobs_.size());
+
+  for (ExecutorList::const_iterator it = executors_.begin();
+       it != executors_.end(); ++it) {
+    const Executor* executor = *it;
+    Job* job = executor->outstanding_job();
+    // The "has_user_callback()" is to exclude jobs for which the callback
+    // has already been invoked, or was not user-initiated (as in the case of
+    // lazy thread provisions). User-initiated jobs may !has_user_callback()
+    // when the callback has already been run. (Since we only clear the
+    // outstanding job AFTER the callback has been invoked, it is possible
+    // for a new request to be started from within the callback).
+    CHECK(!job || job->was_cancelled() || !job->has_user_callback());
+  }
+}
+
+void MultiThreadedProxyResolver::ReleaseAllExecutors() {
+  DCHECK(CalledOnValidThread());
+  for (ExecutorList::iterator it = executors_.begin();
+       it != executors_.end(); ++it) {
+    Executor* executor = *it;
+    executor->Destroy();
+  }
+  executors_.clear();
+}
+
+MultiThreadedProxyResolver::Executor*
+MultiThreadedProxyResolver::FindIdleExecutor() {
+  DCHECK(CalledOnValidThread());
+  for (ExecutorList::iterator it = executors_.begin();
+       it != executors_.end(); ++it) {
+    Executor* executor = *it;
+    if (!executor->outstanding_job())
+      return executor;
+  }
+  return NULL;
+}
+
+MultiThreadedProxyResolver::Executor*
+MultiThreadedProxyResolver::AddNewExecutor() {
+  DCHECK(CalledOnValidThread());
+  DCHECK_LT(executors_.size(), max_num_threads_);
+  // The "thread number" is used to give the thread a unique name.
+  int thread_number = executors_.size();
+  ProxyResolver* resolver = resolver_factory_->CreateProxyResolver();
+  Executor* executor = new Executor(
+      this, resolver, thread_number);
+  executors_.push_back(make_scoped_refptr(executor));
+  return executor;
+}
+
+void MultiThreadedProxyResolver::OnExecutorReady(Executor* executor) {
+  DCHECK(CalledOnValidThread());
+  if (pending_jobs_.empty())
+    return;
+
+  // Get the next job to process (FIFO). Transfer it from the pending queue
+  // to the executor.
+  scoped_refptr<Job> job = pending_jobs_.front();
+  pending_jobs_.pop_front();
+  executor->StartJob(job);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/multi_threaded_proxy_resolver.h b/src/net/proxy/multi_threaded_proxy_resolver.h
new file mode 100644
index 0000000..82a06f5
--- /dev/null
+++ b/src/net/proxy/multi_threaded_proxy_resolver.h
@@ -0,0 +1,145 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_
+#define NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_
+
+#include <deque>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/threading/non_thread_safe.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_resolver.h"
+
+namespace base {
+class Thread;
+}  // namespace base
+
+namespace net {
+
+// ProxyResolverFactory is an interface for creating ProxyResolver instances.
+class ProxyResolverFactory {
+ public:
+  explicit ProxyResolverFactory(bool resolvers_expect_pac_bytes)
+      : resolvers_expect_pac_bytes_(resolvers_expect_pac_bytes) {}
+
+  virtual ~ProxyResolverFactory() {}
+
+  // Creates a new ProxyResolver. The caller is responsible for freeing this
+  // object.
+  virtual ProxyResolver* CreateProxyResolver() = 0;
+
+  bool resolvers_expect_pac_bytes() const {
+    return resolvers_expect_pac_bytes_;
+  }
+
+ private:
+  bool resolvers_expect_pac_bytes_;
+  DISALLOW_COPY_AND_ASSIGN(ProxyResolverFactory);
+};
+
+// MultiThreadedProxyResolver is a ProxyResolver implementation that runs
+// synchronous ProxyResolver implementations on worker threads.
+//
+// Threads are created lazily on demand, up to a maximum total. The advantage
+// of having a pool of threads, is faster performance. In particular, being
+// able to keep servicing PAC requests even if one blocks its execution.
+//
+// During initialization (SetPacScript), a single thread is spun up to test
+// the script. If this succeeds, we cache the input script, and will re-use
+// this to lazily provision any new threads as needed.
+//
+// For each new thread that we spawn, a corresponding new ProxyResolver is
+// created using ProxyResolverFactory.
+//
+// Because we are creating multiple ProxyResolver instances, this means we
+// are duplicating script contexts for what is ordinarily seen as being a
+// single script. This can affect compatibility on some classes of PAC
+// script:
+//
+// (a) Scripts whose initialization has external dependencies on network or
+//     time may end up successfully initializing on some threads, but not
+//     others. So depending on what thread services the request, the result
+//     may jump between several possibilities.
+//
+// (b) Scripts whose FindProxyForURL() depends on side-effects may now
+//     work differently. For example, a PAC script which was incrementing
+//     a global counter and using that to make a decision. In the
+//     multi-threaded model, each thread may have a different value for this
+//     counter, so it won't globally be seen as monotonically increasing!
+class NET_EXPORT_PRIVATE MultiThreadedProxyResolver
+    : public ProxyResolver,
+      NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+  // Creates an asynchronous ProxyResolver that runs requests on up to
+  // |max_num_threads|.
+  //
+  // For each thread that is created, an accompanying synchronous ProxyResolver
+  // will be provisioned using |resolver_factory|. All methods on these
+  // ProxyResolvers will be called on the one thread, with the exception of
+  // ProxyResolver::Shutdown() which will be called from the origin thread
+  // prior to destruction.
+  //
+  // The constructor takes ownership of |resolver_factory|.
+  MultiThreadedProxyResolver(ProxyResolverFactory* resolver_factory,
+                             size_t max_num_threads);
+
+  virtual ~MultiThreadedProxyResolver();
+
+  // ProxyResolver implementation:
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE;
+  virtual void CancelRequest(RequestHandle request) OVERRIDE;
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE;
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE;
+  virtual void CancelSetPacScript() OVERRIDE;
+  virtual void PurgeMemory() OVERRIDE;
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const CompletionCallback& callback) OVERRIDE;
+
+ private:
+  class Executor;
+  class Job;
+  class SetPacScriptJob;
+  class GetProxyForURLJob;
+  // FIFO queue of pending jobs waiting to be started.
+  // TODO(eroman): Make this priority queue.
+  typedef std::deque<scoped_refptr<Job> > PendingJobsQueue;
+  typedef std::vector<scoped_refptr<Executor> > ExecutorList;
+
+  // Asserts that there are no outstanding user-initiated jobs on any of the
+  // worker threads.
+  void CheckNoOutstandingUserRequests() const;
+
+  // Stops and deletes all of the worker threads.
+  void ReleaseAllExecutors();
+
+  // Returns an idle worker thread which is ready to receive GetProxyForURL()
+  // requests. If all threads are occupied, returns NULL.
+  Executor* FindIdleExecutor();
+
+  // Creates a new worker thread, and appends it to |executors_|.
+  Executor* AddNewExecutor();
+
+  // Starts the next job from |pending_jobs_| if possible.
+  void OnExecutorReady(Executor* executor);
+
+  const scoped_ptr<ProxyResolverFactory> resolver_factory_;
+  const size_t max_num_threads_;
+  PendingJobsQueue pending_jobs_;
+  ExecutorList executors_;
+  scoped_refptr<ProxyResolverScriptData> current_script_data_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_MULTI_THREADED_PROXY_RESOLVER_H_
diff --git a/src/net/proxy/multi_threaded_proxy_resolver_unittest.cc b/src/net/proxy/multi_threaded_proxy_resolver_unittest.cc
new file mode 100644
index 0000000..dbd2f5d
--- /dev/null
+++ b/src/net/proxy/multi_threaded_proxy_resolver_unittest.cc
@@ -0,0 +1,798 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/multi_threaded_proxy_resolver.h"
+
+#include "base/message_loop.h"
+#include "base/stl_util.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/threading/platform_thread.h"
+#include "base/utf_string_conversions.h"
+#include "base/synchronization/waitable_event.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/test_completion_callback.h"
+#include "net/proxy/proxy_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// A synchronous mock ProxyResolver implementation, which can be used in
+// conjunction with MultiThreadedProxyResolver.
+//       - returns a single-item proxy list with the query's host.
+class MockProxyResolver : public ProxyResolver {
+ public:
+  MockProxyResolver()
+      : ProxyResolver(true /*expects_pac_bytes*/),
+        wrong_loop_(MessageLoop::current()),
+        request_count_(0),
+        purge_count_(0) {}
+
+  // ProxyResolver implementation.
+  virtual int GetProxyForURL(const GURL& query_url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE {
+    if (resolve_latency_ != base::TimeDelta())
+      base::PlatformThread::Sleep(resolve_latency_);
+
+    CheckIsOnWorkerThread();
+
+    EXPECT_TRUE(callback.is_null());
+    EXPECT_TRUE(request == NULL);
+
+    // Write something into |net_log| (doesn't really have any meaning.)
+    net_log.BeginEvent(NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE);
+
+    results->UseNamedProxy(query_url.host());
+
+    // Return a success code which represents the request's order.
+    return request_count_++;
+  }
+
+  virtual void CancelRequest(RequestHandle request) OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual void CancelSetPacScript() OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const CompletionCallback& callback) OVERRIDE {
+    CheckIsOnWorkerThread();
+    last_script_data_ = script_data;
+    return OK;
+  }
+
+  virtual void PurgeMemory() OVERRIDE {
+    CheckIsOnWorkerThread();
+    ++purge_count_;
+  }
+
+  int purge_count() const { return purge_count_; }
+  int request_count() const { return request_count_; }
+
+  const ProxyResolverScriptData* last_script_data() const {
+    return last_script_data_;
+  }
+
+  void SetResolveLatency(base::TimeDelta latency) {
+    resolve_latency_ = latency;
+  }
+
+ private:
+  void CheckIsOnWorkerThread() {
+    // We should be running on the worker thread -- while we don't know the
+    // message loop of MultiThreadedProxyResolver's worker thread, we do
+    // know that it is going to be distinct from the loop running the
+    // test, so at least make sure it isn't the main loop.
+    EXPECT_NE(MessageLoop::current(), wrong_loop_);
+  }
+
+  MessageLoop* wrong_loop_;
+  int request_count_;
+  int purge_count_;
+  scoped_refptr<ProxyResolverScriptData> last_script_data_;
+  base::TimeDelta resolve_latency_;
+};
+
+
+// A mock synchronous ProxyResolver which can be set to block upon reaching
+// GetProxyForURL().
+// TODO(eroman): WaitUntilBlocked() *must* be called before calling Unblock(),
+//               otherwise there will be a race on |should_block_| since it is
+//               read without any synchronization.
+class BlockableProxyResolver : public MockProxyResolver {
+ public:
+  BlockableProxyResolver()
+      : should_block_(false),
+        unblocked_(true, true),
+        blocked_(true, false) {
+  }
+
+  void Block() {
+    should_block_ = true;
+    unblocked_.Reset();
+  }
+
+  void Unblock() {
+    should_block_ = false;
+    blocked_.Reset();
+    unblocked_.Signal();
+  }
+
+  void WaitUntilBlocked() {
+    blocked_.Wait();
+  }
+
+  virtual int GetProxyForURL(const GURL& query_url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE {
+    if (should_block_) {
+      blocked_.Signal();
+      unblocked_.Wait();
+    }
+
+    return MockProxyResolver::GetProxyForURL(
+        query_url, results, callback, request, net_log);
+  }
+
+ private:
+  bool should_block_;
+  base::WaitableEvent unblocked_;
+  base::WaitableEvent blocked_;
+};
+
+// ForwardingProxyResolver forwards all requests to |impl|.
+class ForwardingProxyResolver : public ProxyResolver {
+ public:
+  explicit ForwardingProxyResolver(ProxyResolver* impl)
+      : ProxyResolver(impl->expects_pac_bytes()),
+        impl_(impl) {}
+
+  virtual int GetProxyForURL(const GURL& query_url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE {
+    return impl_->GetProxyForURL(
+        query_url, results, callback, request, net_log);
+  }
+
+  virtual void CancelRequest(RequestHandle request) OVERRIDE {
+    impl_->CancelRequest(request);
+  }
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual void CancelSetPacScript() OVERRIDE {
+    impl_->CancelSetPacScript();
+  }
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const CompletionCallback& callback) OVERRIDE {
+    return impl_->SetPacScript(script_data, callback);
+  }
+
+  virtual void PurgeMemory() OVERRIDE {
+    impl_->PurgeMemory();
+  }
+
+ private:
+  ProxyResolver* impl_;
+};
+
+// This factory returns ProxyResolvers that forward all requests to
+// |resolver|.
+class ForwardingProxyResolverFactory : public ProxyResolverFactory {
+ public:
+  explicit ForwardingProxyResolverFactory(ProxyResolver* resolver)
+      : ProxyResolverFactory(resolver->expects_pac_bytes()),
+        resolver_(resolver) {}
+
+  virtual ProxyResolver* CreateProxyResolver() OVERRIDE {
+    return new ForwardingProxyResolver(resolver_);
+  }
+
+ private:
+  ProxyResolver* resolver_;
+};
+
+// This factory returns new instances of BlockableProxyResolver.
+class BlockableProxyResolverFactory : public ProxyResolverFactory {
+ public:
+  BlockableProxyResolverFactory() : ProxyResolverFactory(true) {}
+
+  ~BlockableProxyResolverFactory() {
+    STLDeleteElements(&resolvers_);
+  }
+
+  virtual ProxyResolver* CreateProxyResolver() OVERRIDE {
+    BlockableProxyResolver* resolver = new BlockableProxyResolver;
+    resolvers_.push_back(resolver);
+    return new ForwardingProxyResolver(resolver);
+  }
+
+  std::vector<BlockableProxyResolver*> resolvers() {
+    return resolvers_;
+  }
+
+ private:
+  std::vector<BlockableProxyResolver*> resolvers_;
+};
+
+TEST(MultiThreadedProxyResolverTest, SingleThread_Basic) {
+  const size_t kNumThreads = 1u;
+  scoped_ptr<MockProxyResolver> mock(new MockProxyResolver);
+  MultiThreadedProxyResolver resolver(
+      new ForwardingProxyResolverFactory(mock.get()), kNumThreads);
+
+  int rv;
+
+  EXPECT_TRUE(resolver.expects_pac_bytes());
+
+  // Call SetPacScriptByData() -- verify that it reaches the synchronous
+  // resolver.
+  TestCompletionCallback set_script_callback;
+  rv = resolver.SetPacScript(
+      ProxyResolverScriptData::FromUTF8("pac script bytes"),
+      set_script_callback.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  EXPECT_EQ(OK, set_script_callback.WaitForResult());
+  EXPECT_EQ(ASCIIToUTF16("pac script bytes"),
+            mock->last_script_data()->utf16());
+
+  // Start request 0.
+  TestCompletionCallback callback0;
+  CapturingBoundNetLog log0;
+  ProxyInfo results0;
+  rv = resolver.GetProxyForURL(GURL("http://request0"), &results0,
+                               callback0.callback(), NULL, log0.bound());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Wait for request 0 to finish.
+  rv = callback0.WaitForResult();
+  EXPECT_EQ(0, rv);
+  EXPECT_EQ("PROXY request0:80", results0.ToPacString());
+
+  // The mock proxy resolver should have written 1 log entry. And
+  // on completion, this should have been copied into |log0|.
+  // We also have 1 log entry that was emitted by the
+  // MultiThreadedProxyResolver.
+  CapturingNetLog::CapturedEntryList entries0;
+  log0.GetEntries(&entries0);
+
+  ASSERT_EQ(2u, entries0.size());
+  EXPECT_EQ(NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, entries0[0].type);
+
+  // Start 3 more requests (request1 to request3).
+
+  TestCompletionCallback callback1;
+  ProxyInfo results1;
+  rv = resolver.GetProxyForURL(GURL("http://request1"), &results1,
+                               callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TestCompletionCallback callback2;
+  ProxyInfo results2;
+  rv = resolver.GetProxyForURL(GURL("http://request2"), &results2,
+                               callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TestCompletionCallback callback3;
+  ProxyInfo results3;
+  rv = resolver.GetProxyForURL(GURL("http://request3"), &results3,
+                               callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Wait for the requests to finish (they must finish in the order they were
+  // started, which is what we check for from their magic return value)
+
+  rv = callback1.WaitForResult();
+  EXPECT_EQ(1, rv);
+  EXPECT_EQ("PROXY request1:80", results1.ToPacString());
+
+  rv = callback2.WaitForResult();
+  EXPECT_EQ(2, rv);
+  EXPECT_EQ("PROXY request2:80", results2.ToPacString());
+
+  rv = callback3.WaitForResult();
+  EXPECT_EQ(3, rv);
+  EXPECT_EQ("PROXY request3:80", results3.ToPacString());
+
+  // Ensure that PurgeMemory() reaches the wrapped resolver and happens on the
+  // right thread.
+  EXPECT_EQ(0, mock->purge_count());
+  resolver.PurgeMemory();
+  // There is no way to get a callback directly when PurgeMemory() completes, so
+  // we queue up a dummy request after the PurgeMemory() call and wait until it
+  // finishes to ensure PurgeMemory() has had a chance to run.
+  TestCompletionCallback dummy_callback;
+  rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("dummy"),
+                             dummy_callback.callback());
+  EXPECT_EQ(OK, dummy_callback.WaitForResult());
+  EXPECT_EQ(1, mock->purge_count());
+}
+
+// Tests that the NetLog is updated to include the time the request was waiting
+// to be scheduled to a thread.
+TEST(MultiThreadedProxyResolverTest,
+     SingleThread_UpdatesNetLogWithThreadWait) {
+  const size_t kNumThreads = 1u;
+  scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver);
+  MultiThreadedProxyResolver resolver(
+      new ForwardingProxyResolverFactory(mock.get()), kNumThreads);
+
+  int rv;
+
+  // Initialize the resolver.
+  TestCompletionCallback init_callback;
+  rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"),
+                             init_callback.callback());
+  EXPECT_EQ(OK, init_callback.WaitForResult());
+
+  // Block the proxy resolver, so no request can complete.
+  mock->Block();
+
+  // Start request 0.
+  ProxyResolver::RequestHandle request0;
+  TestCompletionCallback callback0;
+  ProxyInfo results0;
+  CapturingBoundNetLog log0;
+  rv = resolver.GetProxyForURL(GURL("http://request0"), &results0,
+                               callback0.callback(), &request0, log0.bound());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Start 2 more requests (request1 and request2).
+
+  TestCompletionCallback callback1;
+  ProxyInfo results1;
+  CapturingBoundNetLog log1;
+  rv = resolver.GetProxyForURL(GURL("http://request1"), &results1,
+                               callback1.callback(), NULL, log1.bound());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyResolver::RequestHandle request2;
+  TestCompletionCallback callback2;
+  ProxyInfo results2;
+  CapturingBoundNetLog log2;
+  rv = resolver.GetProxyForURL(GURL("http://request2"), &results2,
+                               callback2.callback(), &request2, log2.bound());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Unblock the worker thread so the requests can continue running.
+  mock->WaitUntilBlocked();
+  mock->Unblock();
+
+  // Check that request 0 completed as expected.
+  // The NetLog has 1 entry that came from the MultiThreadedProxyResolver, and
+  // 1 entry from the mock proxy resolver.
+  EXPECT_EQ(0, callback0.WaitForResult());
+  EXPECT_EQ("PROXY request0:80", results0.ToPacString());
+
+  CapturingNetLog::CapturedEntryList entries0;
+  log0.GetEntries(&entries0);
+
+  ASSERT_EQ(2u, entries0.size());
+  EXPECT_EQ(NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD,
+            entries0[0].type);
+
+  // Check that request 1 completed as expected.
+  EXPECT_EQ(1, callback1.WaitForResult());
+  EXPECT_EQ("PROXY request1:80", results1.ToPacString());
+
+  CapturingNetLog::CapturedEntryList entries1;
+  log1.GetEntries(&entries1);
+
+  ASSERT_EQ(4u, entries1.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries1, 0,
+      NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries1, 1,
+      NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD));
+
+  // Check that request 2 completed as expected.
+  EXPECT_EQ(2, callback2.WaitForResult());
+  EXPECT_EQ("PROXY request2:80", results2.ToPacString());
+
+  CapturingNetLog::CapturedEntryList entries2;
+  log2.GetEntries(&entries2);
+
+  ASSERT_EQ(4u, entries2.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries2, 0,
+      NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries2, 1,
+      NetLog::TYPE_WAITING_FOR_PROXY_RESOLVER_THREAD));
+}
+
+// Cancel a request which is in progress, and then cancel a request which
+// is pending.
+TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) {
+  const size_t kNumThreads = 1u;
+  scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver);
+  MultiThreadedProxyResolver resolver(
+      new ForwardingProxyResolverFactory(mock.get()),
+                                      kNumThreads);
+
+  int rv;
+
+  // Initialize the resolver.
+  TestCompletionCallback init_callback;
+  rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"),
+                             init_callback.callback());
+  EXPECT_EQ(OK, init_callback.WaitForResult());
+
+  // Block the proxy resolver, so no request can complete.
+  mock->Block();
+
+  // Start request 0.
+  ProxyResolver::RequestHandle request0;
+  TestCompletionCallback callback0;
+  ProxyInfo results0;
+  rv = resolver.GetProxyForURL(GURL("http://request0"), &results0,
+                               callback0.callback(), &request0, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Wait until requests 0 reaches the worker thread.
+  mock->WaitUntilBlocked();
+
+  // Start 3 more requests (request1 : request3).
+
+  TestCompletionCallback callback1;
+  ProxyInfo results1;
+  rv = resolver.GetProxyForURL(GURL("http://request1"), &results1,
+                               callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyResolver::RequestHandle request2;
+  TestCompletionCallback callback2;
+  ProxyInfo results2;
+  rv = resolver.GetProxyForURL(GURL("http://request2"), &results2,
+                               callback2.callback(), &request2, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TestCompletionCallback callback3;
+  ProxyInfo results3;
+  rv = resolver.GetProxyForURL(GURL("http://request3"), &results3,
+                               callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Cancel request0 (inprogress) and request2 (pending).
+  resolver.CancelRequest(request0);
+  resolver.CancelRequest(request2);
+
+  // Unblock the worker thread so the requests can continue running.
+  mock->Unblock();
+
+  // Wait for requests 1 and 3 to finish.
+
+  rv = callback1.WaitForResult();
+  EXPECT_EQ(1, rv);
+  EXPECT_EQ("PROXY request1:80", results1.ToPacString());
+
+  rv = callback3.WaitForResult();
+  // Note that since request2 was cancelled before reaching the resolver,
+  // the request count is 2 and not 3 here.
+  EXPECT_EQ(2, rv);
+  EXPECT_EQ("PROXY request3:80", results3.ToPacString());
+
+  // Requests 0 and 2 which were cancelled, hence their completion callbacks
+  // were never summoned.
+  EXPECT_FALSE(callback0.have_result());
+  EXPECT_FALSE(callback2.have_result());
+}
+
+// Test that deleting MultiThreadedProxyResolver while requests are
+// outstanding cancels them (and doesn't leak anything).
+TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequestByDeleting) {
+  const size_t kNumThreads = 1u;
+  scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver);
+  scoped_ptr<MultiThreadedProxyResolver> resolver(
+      new MultiThreadedProxyResolver(
+          new ForwardingProxyResolverFactory(mock.get()), kNumThreads));
+
+  int rv;
+
+  // Initialize the resolver.
+  TestCompletionCallback init_callback;
+  rv = resolver->SetPacScript(ProxyResolverScriptData::FromUTF8("foo"),
+                              init_callback.callback());
+  EXPECT_EQ(OK, init_callback.WaitForResult());
+
+  // Block the proxy resolver, so no request can complete.
+  mock->Block();
+
+  // Start 3 requests.
+
+  TestCompletionCallback callback0;
+  ProxyInfo results0;
+  rv = resolver->GetProxyForURL(GURL("http://request0"), &results0,
+                                callback0.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TestCompletionCallback callback1;
+  ProxyInfo results1;
+  rv = resolver->GetProxyForURL(GURL("http://request1"), &results1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  TestCompletionCallback callback2;
+  ProxyInfo results2;
+  rv = resolver->GetProxyForURL(GURL("http://request2"), &results2,
+                                callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Wait until request 0 reaches the worker thread.
+  mock->WaitUntilBlocked();
+
+  // Add some latency, to improve the chance that when
+  // MultiThreadedProxyResolver is deleted below we are still running inside
+  // of the worker thread. The test will pass regardless, so this race doesn't
+  // cause flakiness. However the destruction during execution is a more
+  // interesting case to test.
+  mock->SetResolveLatency(base::TimeDelta::FromMilliseconds(100));
+
+  // Unblock the worker thread and delete the underlying
+  // MultiThreadedProxyResolver immediately.
+  mock->Unblock();
+  resolver.reset();
+
+  // Give any posted tasks a chance to run (in case there is badness).
+  MessageLoop::current()->RunUntilIdle();
+
+  // Check that none of the outstanding requests were completed.
+  EXPECT_FALSE(callback0.have_result());
+  EXPECT_FALSE(callback1.have_result());
+  EXPECT_FALSE(callback2.have_result());
+}
+
+// Cancel an outstanding call to SetPacScriptByData().
+TEST(MultiThreadedProxyResolverTest, SingleThread_CancelSetPacScript) {
+  const size_t kNumThreads = 1u;
+  scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver);
+  MultiThreadedProxyResolver resolver(
+      new ForwardingProxyResolverFactory(mock.get()), kNumThreads);
+
+  int rv;
+
+  TestCompletionCallback set_pac_script_callback;
+  rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data"),
+                             set_pac_script_callback.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Cancel the SetPacScriptByData request.
+  resolver.CancelSetPacScript();
+
+  // Start another SetPacScript request
+  TestCompletionCallback set_pac_script_callback2;
+  rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data2"),
+                             set_pac_script_callback2.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Wait for the initialization to complete.
+
+  rv = set_pac_script_callback2.WaitForResult();
+  EXPECT_EQ(0, rv);
+  EXPECT_EQ(ASCIIToUTF16("data2"), mock->last_script_data()->utf16());
+
+  // The first SetPacScript callback should never have been completed.
+  EXPECT_FALSE(set_pac_script_callback.have_result());
+}
+
+// Tests setting the PAC script once, lazily creating new threads, and
+// cancelling requests.
+TEST(MultiThreadedProxyResolverTest, ThreeThreads_Basic) {
+  const size_t kNumThreads = 3u;
+  BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory;
+  MultiThreadedProxyResolver resolver(factory, kNumThreads);
+
+  int rv;
+
+  EXPECT_TRUE(resolver.expects_pac_bytes());
+
+  // Call SetPacScriptByData() -- verify that it reaches the synchronous
+  // resolver.
+  TestCompletionCallback set_script_callback;
+  rv = resolver.SetPacScript(
+      ProxyResolverScriptData::FromUTF8("pac script bytes"),
+      set_script_callback.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  EXPECT_EQ(OK, set_script_callback.WaitForResult());
+  // One thread has been provisioned (i.e. one ProxyResolver was created).
+  ASSERT_EQ(1u, factory->resolvers().size());
+  EXPECT_EQ(ASCIIToUTF16("pac script bytes"),
+            factory->resolvers()[0]->last_script_data()->utf16());
+
+  const int kNumRequests = 9;
+  TestCompletionCallback callback[kNumRequests];
+  ProxyInfo results[kNumRequests];
+  ProxyResolver::RequestHandle request[kNumRequests];
+
+  // Start request 0 -- this should run on thread 0 as there is nothing else
+  // going on right now.
+  rv = resolver.GetProxyForURL(
+      GURL("http://request0"), &results[0], callback[0].callback(), &request[0],
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Wait for request 0 to finish.
+  rv = callback[0].WaitForResult();
+  EXPECT_EQ(0, rv);
+  EXPECT_EQ("PROXY request0:80", results[0].ToPacString());
+  ASSERT_EQ(1u, factory->resolvers().size());
+  EXPECT_EQ(1, factory->resolvers()[0]->request_count());
+
+  MessageLoop::current()->RunUntilIdle();
+
+  // We now start 8 requests in parallel -- this will cause the maximum of
+  // three threads to be provisioned (an additional two from what we already
+  // have).
+
+  for (int i = 1; i < kNumRequests; ++i) {
+    rv = resolver.GetProxyForURL(
+        GURL(base::StringPrintf("http://request%d", i)), &results[i],
+        callback[i].callback(), &request[i], BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+  }
+
+  // We should now have a total of 3 threads, each with its own ProxyResolver
+  // that will get initialized with the same data. (We check this later since
+  // the assignment happens on the worker threads and may not have occurred
+  // yet.)
+  ASSERT_EQ(3u, factory->resolvers().size());
+
+  // Cancel 3 of the 8 oustanding requests.
+  resolver.CancelRequest(request[1]);
+  resolver.CancelRequest(request[3]);
+  resolver.CancelRequest(request[6]);
+
+  // Wait for the remaining requests to complete.
+  int kNonCancelledRequests[] = {2, 4, 5, 7, 8};
+  for (size_t i = 0; i < arraysize(kNonCancelledRequests); ++i) {
+    int request_index = kNonCancelledRequests[i];
+    EXPECT_GE(callback[request_index].WaitForResult(), 0);
+  }
+
+  // Check that the cancelled requests never invoked their callback.
+  EXPECT_FALSE(callback[1].have_result());
+  EXPECT_FALSE(callback[3].have_result());
+  EXPECT_FALSE(callback[6].have_result());
+
+  // We call SetPacScript again, solely to stop the current worker threads.
+  // (That way we can test to see the values observed by the synchronous
+  // resolvers in a non-racy manner).
+  TestCompletionCallback set_script_callback2;
+  rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("xyz"),
+                             set_script_callback2.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  EXPECT_EQ(OK, set_script_callback2.WaitForResult());
+  ASSERT_EQ(4u, factory->resolvers().size());
+
+  for (int i = 0; i < 3; ++i) {
+    EXPECT_EQ(
+        ASCIIToUTF16("pac script bytes"),
+        factory->resolvers()[i]->last_script_data()->utf16()) << "i=" << i;
+  }
+
+  EXPECT_EQ(ASCIIToUTF16("xyz"),
+            factory->resolvers()[3]->last_script_data()->utf16());
+
+  // We don't know the exact ordering that requests ran on threads with,
+  // but we do know the total count that should have reached the threads.
+  // 8 total were submitted, and three were cancelled. Of the three that
+  // were cancelled, one of them (request 1) was cancelled after it had
+  // already been posted to the worker thread. So the resolvers will
+  // have seen 6 total (and 1 from the run prior).
+  ASSERT_EQ(4u, factory->resolvers().size());
+  int total_count = 0;
+  for (int i = 0; i < 3; ++i) {
+    total_count += factory->resolvers()[i]->request_count();
+  }
+  EXPECT_EQ(7, total_count);
+}
+
+// Tests using two threads. The first request hangs the first thread. Checks
+// that other requests are able to complete while this first request remains
+// stalled.
+TEST(MultiThreadedProxyResolverTest, OneThreadBlocked) {
+  const size_t kNumThreads = 2u;
+  BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory;
+  MultiThreadedProxyResolver resolver(factory, kNumThreads);
+
+  int rv;
+
+  EXPECT_TRUE(resolver.expects_pac_bytes());
+
+  // Initialize the resolver.
+  TestCompletionCallback set_script_callback;
+  rv = resolver.SetPacScript(
+      ProxyResolverScriptData::FromUTF8("pac script bytes"),
+      set_script_callback.callback());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  EXPECT_EQ(OK, set_script_callback.WaitForResult());
+  // One thread has been provisioned (i.e. one ProxyResolver was created).
+  ASSERT_EQ(1u, factory->resolvers().size());
+  EXPECT_EQ(ASCIIToUTF16("pac script bytes"),
+            factory->resolvers()[0]->last_script_data()->utf16());
+
+  const int kNumRequests = 4;
+  TestCompletionCallback callback[kNumRequests];
+  ProxyInfo results[kNumRequests];
+  ProxyResolver::RequestHandle request[kNumRequests];
+
+  // Start a request that will block the first thread.
+
+  factory->resolvers()[0]->Block();
+
+  rv = resolver.GetProxyForURL(
+      GURL("http://request0"), &results[0], callback[0].callback(), &request[0],
+      BoundNetLog());
+
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  factory->resolvers()[0]->WaitUntilBlocked();
+
+  // Start 3 more requests -- they should all be serviced by thread #2
+  // since thread #1 is blocked.
+
+  for (int i = 1; i < kNumRequests; ++i) {
+    rv = resolver.GetProxyForURL(
+        GURL(base::StringPrintf("http://request%d", i)),
+        &results[i], callback[i].callback(), &request[i], BoundNetLog());
+    EXPECT_EQ(ERR_IO_PENDING, rv);
+  }
+
+  // Wait for the three requests to complete (they should complete in FIFO
+  // order).
+  for (int i = 1; i < kNumRequests; ++i) {
+    EXPECT_EQ(i - 1, callback[i].WaitForResult());
+  }
+
+  // Unblock the first thread.
+  factory->resolvers()[0]->Unblock();
+  EXPECT_EQ(0, callback[0].WaitForResult());
+
+  // All in all, the first thread should have seen just 1 request. And the
+  // second thread 3 requests.
+  ASSERT_EQ(2u, factory->resolvers().size());
+  EXPECT_EQ(1, factory->resolvers()[0]->request_count());
+  EXPECT_EQ(3, factory->resolvers()[1]->request_count());
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/src/net/proxy/network_delegate_error_observer.cc b/src/net/proxy/network_delegate_error_observer.cc
new file mode 100644
index 0000000..e2412b4
--- /dev/null
+++ b/src/net/proxy/network_delegate_error_observer.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/network_delegate_error_observer.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/message_loop_proxy.h"
+#include "net/base/net_errors.h"
+#include "net/base/network_delegate.h"
+
+namespace net {
+
+// NetworkDelegateErrorObserver::Core -----------------------------------------
+
+class NetworkDelegateErrorObserver::Core
+    : public base::RefCountedThreadSafe<NetworkDelegateErrorObserver::Core> {
+ public:
+  Core(NetworkDelegate* network_delegate, base::MessageLoopProxy* origin_loop);
+
+  void NotifyPACScriptError(int line_number, const string16& error);
+
+  void Shutdown();
+
+ private:
+  friend class base::RefCountedThreadSafe<NetworkDelegateErrorObserver::Core>;
+
+  virtual ~Core();
+
+  NetworkDelegate* network_delegate_;
+  scoped_refptr<base::MessageLoopProxy> origin_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
+NetworkDelegateErrorObserver::Core::Core(NetworkDelegate* network_delegate,
+                                         base::MessageLoopProxy* origin_loop)
+  : network_delegate_(network_delegate),
+    origin_loop_(origin_loop) {
+  DCHECK(origin_loop);
+}
+
+NetworkDelegateErrorObserver::Core::~Core() {}
+
+
+void NetworkDelegateErrorObserver::Core::NotifyPACScriptError(
+    int line_number,
+    const string16& error) {
+  if (!origin_loop_->BelongsToCurrentThread()) {
+    origin_loop_->PostTask(
+        FROM_HERE,
+        base::Bind(&Core::NotifyPACScriptError, this, line_number, error));
+    return;
+  }
+  if (network_delegate_)
+    network_delegate_->NotifyPACScriptError(line_number, error);
+}
+
+void NetworkDelegateErrorObserver::Core::Shutdown() {
+  CHECK(origin_loop_->BelongsToCurrentThread());
+  network_delegate_ = NULL;
+}
+
+// NetworkDelegateErrorObserver -----------------------------------------------
+
+NetworkDelegateErrorObserver::NetworkDelegateErrorObserver(
+    NetworkDelegate* network_delegate,
+    base::MessageLoopProxy* origin_loop)
+    : core_(new Core(network_delegate, origin_loop)) {}
+
+NetworkDelegateErrorObserver::~NetworkDelegateErrorObserver() {
+  core_->Shutdown();
+}
+
+void NetworkDelegateErrorObserver::OnPACScriptError(int line_number,
+                                                    const string16& error) {
+  core_->NotifyPACScriptError(line_number, error);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/network_delegate_error_observer.h b/src/net/proxy/network_delegate_error_observer.h
new file mode 100644
index 0000000..5e691f7
--- /dev/null
+++ b/src/net/proxy/network_delegate_error_observer.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_NETWORK_DELEGATE_ERROR_OBSERVER_H_
+#define NET_PROXY_NETWORK_DELEGATE_ERROR_OBSERVER_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "net/proxy/proxy_resolver_error_observer.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace net {
+
+class NetworkDelegate;
+
+// An implementation of ProxyResolverErrorObserver that forwards PAC script
+// errors to a NetworkDelegate object on the thread it lives on.
+class NET_EXPORT_PRIVATE NetworkDelegateErrorObserver
+    : public ProxyResolverErrorObserver {
+ public:
+  NetworkDelegateErrorObserver(NetworkDelegate* network_delegate,
+                               base::MessageLoopProxy* origin_loop);
+  virtual ~NetworkDelegateErrorObserver();
+
+  // ProxyResolverErrorObserver implementation.
+  virtual void OnPACScriptError(int line_number, const string16& error)
+      OVERRIDE;
+
+ private:
+  class Core;
+
+  scoped_refptr<Core> core_;
+
+  DISALLOW_COPY_AND_ASSIGN(NetworkDelegateErrorObserver);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_NETWORK_DELEGATE_ERROR_OBSERVER_H_
diff --git a/src/net/proxy/network_delegate_error_observer_unittest.cc b/src/net/proxy/network_delegate_error_observer_unittest.cc
new file mode 100644
index 0000000..8b2b51c
--- /dev/null
+++ b/src/net/proxy/network_delegate_error_observer_unittest.cc
@@ -0,0 +1,129 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/network_delegate_error_observer.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/message_loop_proxy.h"
+#include "base/threading/thread.h"
+#include "net/base/net_errors.h"
+#include "net/base/network_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+class TestNetworkDelegate : public net::NetworkDelegate {
+ public:
+  TestNetworkDelegate() : got_pac_error_(false) {}
+  virtual ~TestNetworkDelegate() {}
+
+  bool got_pac_error() const { return got_pac_error_; }
+
+ private:
+  // net::NetworkDelegate implementation.
+  virtual int OnBeforeURLRequest(URLRequest* request,
+                                 const CompletionCallback& callback,
+                                 GURL* new_url) OVERRIDE {
+    return OK;
+  }
+  virtual int OnBeforeSendHeaders(URLRequest* request,
+                                  const CompletionCallback& callback,
+                                  HttpRequestHeaders* headers) OVERRIDE {
+    return OK;
+  }
+  virtual void OnSendHeaders(URLRequest* request,
+                             const HttpRequestHeaders& headers) OVERRIDE {}
+  virtual int OnHeadersReceived(
+      URLRequest* request,
+      const CompletionCallback& callback,
+      const HttpResponseHeaders* original_response_headers,
+      scoped_refptr<HttpResponseHeaders>* override_response_headers) OVERRIDE {
+    return net::OK;
+  }
+  virtual void OnBeforeRedirect(URLRequest* request,
+                                const GURL& new_location) OVERRIDE {}
+  virtual void OnResponseStarted(URLRequest* request) OVERRIDE {}
+  virtual void OnRawBytesRead(const URLRequest& request,
+                              int bytes_read) OVERRIDE {}
+  virtual void OnCompleted(URLRequest* request, bool started) OVERRIDE {}
+  virtual void OnURLRequestDestroyed(URLRequest* request) OVERRIDE {}
+
+  virtual void OnPACScriptError(int line_number,
+                                const string16& error) OVERRIDE {
+    got_pac_error_ = true;
+  }
+  virtual AuthRequiredResponse OnAuthRequired(
+      URLRequest* request,
+      const AuthChallengeInfo& auth_info,
+      const AuthCallback& callback,
+      AuthCredentials* credentials) OVERRIDE {
+    return AUTH_REQUIRED_RESPONSE_NO_ACTION;
+  }
+  virtual bool OnCanGetCookies(const URLRequest& request,
+                               const CookieList& cookie_list) OVERRIDE {
+    return true;
+  }
+  virtual bool OnCanSetCookie(const URLRequest& request,
+                              const std::string& cookie_line,
+                              CookieOptions* options) OVERRIDE {
+    return true;
+  }
+  virtual bool OnCanAccessFile(const net::URLRequest& request,
+                               const FilePath& path) const OVERRIDE {
+    return true;
+  }
+  virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE {
+    return false;
+  }
+  virtual int OnBeforeSocketStreamConnect(
+      SocketStream* stream,
+      const CompletionCallback& callback) OVERRIDE {
+    return OK;
+  }
+  virtual void OnRequestWaitStateChange(const net::URLRequest& request,
+                                        RequestWaitState state) OVERRIDE {
+  }
+
+  bool got_pac_error_;
+};
+
+}  // namespace
+
+// Check that the OnPACScriptError method can be called from an arbitrary
+// thread.
+TEST(NetworkDelegateErrorObserverTest, CallOnThread) {
+  base::Thread thread("test_thread");
+  thread.Start();
+  TestNetworkDelegate network_delegate;
+  NetworkDelegateErrorObserver
+      observer(&network_delegate,
+               base::MessageLoopProxy::current());
+  thread.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&NetworkDelegateErrorObserver::OnPACScriptError,
+                 base::Unretained(&observer), 42, string16()));
+  thread.Stop();
+  MessageLoop::current()->RunUntilIdle();
+  ASSERT_TRUE(network_delegate.got_pac_error());
+}
+
+// Check that passing a NULL network delegate works.
+TEST(NetworkDelegateErrorObserverTest, NoDelegate) {
+  base::Thread thread("test_thread");
+  thread.Start();
+  NetworkDelegateErrorObserver
+      observer(NULL, base::MessageLoopProxy::current());
+  thread.message_loop()->PostTask(
+      FROM_HERE,
+      base::Bind(&NetworkDelegateErrorObserver::OnPACScriptError,
+                 base::Unretained(&observer), 42, string16()));
+  thread.Stop();
+  MessageLoop::current()->RunUntilIdle();
+  // Shouldn't have crashed until here...
+}
+
+}  // namespace net
diff --git a/src/net/proxy/polling_proxy_config_service.cc b/src/net/proxy/polling_proxy_config_service.cc
new file mode 100644
index 0000000..a03422a
--- /dev/null
+++ b/src/net/proxy/polling_proxy_config_service.cc
@@ -0,0 +1,195 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/polling_proxy_config_service.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop_proxy.h"
+#include "base/observer_list.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/worker_pool.h"
+#include "net/proxy/proxy_config.h"
+
+namespace net {
+
+// Reference-counted wrapper that does all the work (needs to be
+// reference-counted since we post tasks between threads; may outlive
+// the parent PollingProxyConfigService).
+class PollingProxyConfigService::Core
+    : public base::RefCountedThreadSafe<PollingProxyConfigService::Core> {
+ public:
+  Core(base::TimeDelta poll_interval,
+       GetConfigFunction get_config_func)
+      : get_config_func_(get_config_func),
+        poll_interval_(poll_interval),
+        have_initialized_origin_loop_(false),
+        has_config_(false),
+        poll_task_outstanding_(false),
+        poll_task_queued_(false) {
+  }
+
+  // Called when the parent PollingProxyConfigService is destroyed
+  // (observers should not be called past this point).
+  void Orphan() {
+    base::AutoLock l(lock_);
+    origin_loop_proxy_ = NULL;
+  }
+
+  bool GetLatestProxyConfig(ProxyConfig* config) {
+    LazyInitializeOriginLoop();
+    DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
+
+    OnLazyPoll();
+
+    // If we have already retrieved the proxy settings (on worker thread)
+    // then return what we last saw.
+    if (has_config_) {
+      *config = last_config_;
+      return true;
+    }
+    return false;
+  }
+
+  void AddObserver(Observer* observer) {
+    LazyInitializeOriginLoop();
+    DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
+    observers_.AddObserver(observer);
+  }
+
+  void RemoveObserver(Observer* observer) {
+    DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
+    observers_.RemoveObserver(observer);
+  }
+
+  // Check for a new configuration if enough time has elapsed.
+  void OnLazyPoll() {
+    LazyInitializeOriginLoop();
+    DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
+
+    if (last_poll_time_.is_null() ||
+        (base::TimeTicks::Now() - last_poll_time_) > poll_interval_) {
+      CheckForChangesNow();
+    }
+  }
+
+  void CheckForChangesNow() {
+    LazyInitializeOriginLoop();
+    DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
+
+    if (poll_task_outstanding_) {
+      // Only allow one task to be outstanding at a time. If we get a poll
+      // request while we are busy, we will defer it until the current poll
+      // completes.
+      poll_task_queued_ = true;
+      return;
+    }
+
+    last_poll_time_ = base::TimeTicks::Now();
+    poll_task_outstanding_ = true;
+    poll_task_queued_ = false;
+    base::WorkerPool::PostTask(
+        FROM_HERE,
+        base::Bind(&Core::PollOnWorkerThread, this, get_config_func_),
+        true);
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<Core>;
+  ~Core() {}
+
+  void PollOnWorkerThread(GetConfigFunction func) {
+    ProxyConfig config;
+    func(&config);
+
+    base::AutoLock l(lock_);
+    if (origin_loop_proxy_) {
+      origin_loop_proxy_->PostTask(
+          FROM_HERE,
+          base::Bind(&Core::GetConfigCompleted, this, config));
+    }
+  }
+
+  // Called after the worker thread has finished retrieving a configuration.
+  void GetConfigCompleted(const ProxyConfig& config) {
+    DCHECK(poll_task_outstanding_);
+    poll_task_outstanding_ = false;
+
+    if (!origin_loop_proxy_)
+      return;  // Was orphaned (parent has already been destroyed).
+
+    DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
+
+    if (!has_config_ || !last_config_.Equals(config)) {
+      // If the configuration has changed, notify the observers.
+      has_config_ = true;
+      last_config_ = config;
+      FOR_EACH_OBSERVER(Observer, observers_,
+                        OnProxyConfigChanged(config,
+                                             ProxyConfigService::CONFIG_VALID));
+    }
+
+    if (poll_task_queued_)
+      CheckForChangesNow();
+  }
+
+  void LazyInitializeOriginLoop() {
+    // TODO(eroman): Really this should be done in the constructor, but right
+    //               now chrome is constructing the ProxyConfigService on the
+    //               UI thread so we can't cache the IO thread for the purpose
+    //               of DCHECKs until the first call is made.
+    if (!have_initialized_origin_loop_) {
+      origin_loop_proxy_ = base::MessageLoopProxy::current();
+      have_initialized_origin_loop_ = true;
+    }
+  }
+
+  GetConfigFunction get_config_func_;
+  ObserverList<Observer> observers_;
+  ProxyConfig last_config_;
+  base::TimeTicks last_poll_time_;
+  base::TimeDelta poll_interval_;
+
+  base::Lock lock_;
+  scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_;
+
+  bool have_initialized_origin_loop_;
+  bool has_config_;
+  bool poll_task_outstanding_;
+  bool poll_task_queued_;
+};
+
+void PollingProxyConfigService::AddObserver(Observer* observer) {
+  core_->AddObserver(observer);
+}
+
+void PollingProxyConfigService::RemoveObserver(Observer* observer) {
+  core_->RemoveObserver(observer);
+}
+
+ProxyConfigService::ConfigAvailability
+    PollingProxyConfigService::GetLatestProxyConfig(ProxyConfig* config) {
+  return core_->GetLatestProxyConfig(config) ? CONFIG_VALID : CONFIG_PENDING;
+}
+
+void PollingProxyConfigService::OnLazyPoll() {
+  core_->OnLazyPoll();
+}
+
+PollingProxyConfigService::PollingProxyConfigService(
+    base::TimeDelta poll_interval,
+    GetConfigFunction get_config_func)
+    : core_(new Core(poll_interval, get_config_func)) {
+}
+
+PollingProxyConfigService::~PollingProxyConfigService() {
+  core_->Orphan();
+}
+
+void PollingProxyConfigService::CheckForChangesNow() {
+  core_->CheckForChangesNow();
+}
+
+}  // namespace net
diff --git a/src/net/proxy/polling_proxy_config_service.h b/src/net/proxy/polling_proxy_config_service.h
new file mode 100644
index 0000000..2792f24
--- /dev/null
+++ b/src/net/proxy/polling_proxy_config_service.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_POLLING_PROXY_CONFIG_SERVICE_H_
+#define NET_PROXY_POLLING_PROXY_CONFIG_SERVICE_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/time.h"
+#include "net/proxy/proxy_config_service.h"
+
+namespace net {
+
+// PollingProxyConfigService is a base class for creating ProxyConfigService
+// implementations that use polling to notice when settings have change.
+//
+// It runs code to get the current proxy settings on a background worker
+// thread, and notifies registered observers when the value changes.
+class NET_EXPORT_PRIVATE PollingProxyConfigService : public ProxyConfigService {
+ public:
+  // ProxyConfigService implementation:
+  virtual void AddObserver(Observer* observer) OVERRIDE;
+  virtual void RemoveObserver(Observer* observer) OVERRIDE;
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) OVERRIDE;
+  virtual void OnLazyPoll() OVERRIDE;
+
+ protected:
+  // Function for retrieving the current proxy configuration.
+  // Implementors must be threadsafe as the function will be invoked from
+  // worker threads.
+  typedef void (*GetConfigFunction)(ProxyConfig*);
+
+  // Creates a polling-based ProxyConfigService which will test for new
+  // settings at most every |poll_interval| time by calling |get_config_func|
+  // on a worker thread.
+  PollingProxyConfigService(
+      base::TimeDelta poll_interval,
+      GetConfigFunction get_config_func);
+
+  virtual ~PollingProxyConfigService();
+
+  // Polls for changes by posting a task to the worker pool.
+  void CheckForChangesNow();
+
+ private:
+  class Core;
+  scoped_refptr<Core> core_;
+
+  DISALLOW_COPY_AND_ASSIGN(PollingProxyConfigService);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_POLLING_PROXY_CONFIG_SERVICE_H_
diff --git a/src/net/proxy/proxy_bypass_rules.cc b/src/net/proxy/proxy_bypass_rules.cc
new file mode 100644
index 0000000..1c0fd61
--- /dev/null
+++ b/src/net/proxy/proxy_bypass_rules.cc
@@ -0,0 +1,347 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/proxy_bypass_rules.h"
+
+#include "base/stl_util.h"
+#include "base/stringprintf.h"
+#include "base/string_number_conversions.h"
+#include "base/string_piece.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "net/base/net_util.h"
+
+namespace net {
+
+namespace {
+
+class HostnamePatternRule : public ProxyBypassRules::Rule {
+ public:
+  HostnamePatternRule(const std::string& optional_scheme,
+                      const std::string& hostname_pattern,
+                      int optional_port)
+      : optional_scheme_(StringToLowerASCII(optional_scheme)),
+        hostname_pattern_(StringToLowerASCII(hostname_pattern)),
+        optional_port_(optional_port) {
+  }
+
+  virtual bool Matches(const GURL& url) const OVERRIDE {
+    if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_)
+      return false;  // Didn't match port expectation.
+
+    if (!optional_scheme_.empty() && url.scheme() != optional_scheme_)
+      return false;  // Didn't match scheme expectation.
+
+    // Note it is necessary to lower-case the host, since GURL uses capital
+    // letters for percent-escaped characters.
+    return MatchPattern(StringToLowerASCII(url.host()), hostname_pattern_);
+  }
+
+  virtual std::string ToString() const OVERRIDE {
+    std::string str;
+    if (!optional_scheme_.empty())
+      base::StringAppendF(&str, "%s://", optional_scheme_.c_str());
+    str += hostname_pattern_;
+    if (optional_port_ != -1)
+      base::StringAppendF(&str, ":%d", optional_port_);
+    return str;
+  }
+
+  virtual Rule* Clone() const OVERRIDE {
+    return new HostnamePatternRule(optional_scheme_,
+                                   hostname_pattern_,
+                                   optional_port_);
+  }
+
+ private:
+  const std::string optional_scheme_;
+  const std::string hostname_pattern_;
+  const int optional_port_;
+};
+
+class BypassLocalRule : public ProxyBypassRules::Rule {
+ public:
+  virtual bool Matches(const GURL& url) const OVERRIDE {
+    const std::string& host = url.host();
+    if (host == "127.0.0.1" || host == "[::1]")
+      return true;
+    return host.find('.') == std::string::npos;
+  }
+
+  virtual std::string ToString() const OVERRIDE {
+    return "<local>";
+  }
+
+  virtual Rule* Clone() const OVERRIDE {
+    return new BypassLocalRule();
+  }
+};
+
+// Rule for matching a URL that is an IP address, if that IP address falls
+// within a certain numeric range. For example, you could use this rule to
+// match all the IPs in the CIDR block 10.10.3.4/24.
+class BypassIPBlockRule : public ProxyBypassRules::Rule {
+ public:
+  // |ip_prefix| + |prefix_length| define the IP block to match.
+  BypassIPBlockRule(const std::string& description,
+                    const std::string& optional_scheme,
+                    const IPAddressNumber& ip_prefix,
+                    size_t prefix_length_in_bits)
+      : description_(description),
+        optional_scheme_(optional_scheme),
+        ip_prefix_(ip_prefix),
+        prefix_length_in_bits_(prefix_length_in_bits) {
+  }
+
+  virtual bool Matches(const GURL& url) const OVERRIDE {
+    if (!url.HostIsIPAddress())
+      return false;
+
+    if (!optional_scheme_.empty() && url.scheme() != optional_scheme_)
+      return false;  // Didn't match scheme expectation.
+
+    // Parse the input IP literal to a number.
+    IPAddressNumber ip_number;
+    if (!ParseIPLiteralToNumber(url.HostNoBrackets(), &ip_number))
+      return false;
+
+    // Test if it has the expected prefix.
+    return IPNumberMatchesPrefix(ip_number, ip_prefix_,
+                                 prefix_length_in_bits_);
+  }
+
+  virtual std::string ToString() const OVERRIDE {
+    return description_;
+  }
+
+  virtual Rule* Clone() const OVERRIDE {
+    return new BypassIPBlockRule(description_,
+                                 optional_scheme_,
+                                 ip_prefix_,
+                                 prefix_length_in_bits_);
+  }
+
+ private:
+  const std::string description_;
+  const std::string optional_scheme_;
+  const IPAddressNumber ip_prefix_;
+  const size_t prefix_length_in_bits_;
+};
+
+// Returns true if the given string represents an IP address.
+bool IsIPAddress(const std::string& domain) {
+  // From GURL::HostIsIPAddress()
+  url_canon::RawCanonOutputT<char, 128> ignored_output;
+  url_canon::CanonHostInfo host_info;
+  url_parse::Component domain_comp(0, domain.size());
+  url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
+                                   &ignored_output, &host_info);
+  return host_info.IsIPAddress();
+}
+
+}  // namespace
+
+ProxyBypassRules::Rule::Rule() {
+}
+
+ProxyBypassRules::Rule::~Rule() {
+}
+
+bool ProxyBypassRules::Rule::Equals(const Rule& rule) const {
+  return ToString() == rule.ToString();
+}
+
+ProxyBypassRules::ProxyBypassRules() {
+}
+
+ProxyBypassRules::ProxyBypassRules(const ProxyBypassRules& rhs) {
+  AssignFrom(rhs);
+}
+
+ProxyBypassRules::~ProxyBypassRules() {
+  Clear();
+}
+
+ProxyBypassRules& ProxyBypassRules::operator=(const ProxyBypassRules& rhs) {
+  AssignFrom(rhs);
+  return *this;
+}
+
+bool ProxyBypassRules::Matches(const GURL& url) const {
+  for (RuleList::const_iterator it = rules_.begin(); it != rules_.end(); ++it) {
+    if ((*it)->Matches(url))
+      return true;
+  }
+  return false;
+}
+
+bool ProxyBypassRules::Equals(const ProxyBypassRules& other) const {
+  if (rules_.size() != other.rules_.size())
+    return false;
+
+  for (size_t i = 0; i < rules_.size(); ++i) {
+    if (!rules_[i]->Equals(*other.rules_[i]))
+      return false;
+  }
+  return true;
+}
+
+void ProxyBypassRules::ParseFromString(const std::string& raw) {
+  ParseFromStringInternal(raw, false);
+}
+
+void ProxyBypassRules::ParseFromStringUsingSuffixMatching(
+    const std::string& raw) {
+  ParseFromStringInternal(raw, true);
+}
+
+bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme,
+                                          const std::string& hostname_pattern,
+                                          int optional_port) {
+  if (hostname_pattern.empty())
+    return false;
+
+  rules_.push_back(new HostnamePatternRule(optional_scheme,
+                                           hostname_pattern,
+                                           optional_port));
+  return true;
+}
+
+void ProxyBypassRules::AddRuleToBypassLocal() {
+  rules_.push_back(new BypassLocalRule);
+}
+
+bool ProxyBypassRules::AddRuleFromString(const std::string& raw) {
+  return AddRuleFromStringInternalWithLogging(raw, false);
+}
+
+bool ProxyBypassRules::AddRuleFromStringUsingSuffixMatching(
+    const std::string& raw) {
+  return AddRuleFromStringInternalWithLogging(raw, true);
+}
+
+std::string ProxyBypassRules::ToString() const {
+  std::string result;
+  for (RuleList::const_iterator rule(rules_.begin());
+       rule != rules_.end();
+       ++rule) {
+    result += (*rule)->ToString();
+    result += ";";
+  }
+  return result;
+}
+
+void ProxyBypassRules::Clear() {
+  STLDeleteElements(&rules_);
+}
+
+void ProxyBypassRules::AssignFrom(const ProxyBypassRules& other) {
+  Clear();
+
+  // Make a copy of the rules list.
+  for (RuleList::const_iterator it = other.rules_.begin();
+       it != other.rules_.end(); ++it) {
+    rules_.push_back((*it)->Clone());
+  }
+}
+
+void ProxyBypassRules::ParseFromStringInternal(
+    const std::string& raw,
+    bool use_hostname_suffix_matching) {
+  Clear();
+
+  StringTokenizer entries(raw, ",;");
+  while (entries.GetNext()) {
+    AddRuleFromStringInternalWithLogging(entries.token(),
+                                         use_hostname_suffix_matching);
+  }
+}
+
+bool ProxyBypassRules::AddRuleFromStringInternal(
+    const std::string& raw_untrimmed,
+    bool use_hostname_suffix_matching) {
+  std::string raw;
+  TrimWhitespaceASCII(raw_untrimmed, TRIM_ALL, &raw);
+
+  // This is the special syntax used by WinInet's bypass list -- we allow it
+  // on all platforms and interpret it the same way.
+  if (LowerCaseEqualsASCII(raw, "<local>")) {
+    AddRuleToBypassLocal();
+    return true;
+  }
+
+  // Extract any scheme-restriction.
+  std::string::size_type scheme_pos = raw.find("://");
+  std::string scheme;
+  if (scheme_pos != std::string::npos) {
+    scheme = raw.substr(0, scheme_pos);
+    raw = raw.substr(scheme_pos + 3);
+    if (scheme.empty())
+      return false;
+  }
+
+  if (raw.empty())
+    return false;
+
+  // If there is a forward slash in the input, it is probably a CIDR style
+  // mask.
+  if (raw.find('/') != std::string::npos) {
+    IPAddressNumber ip_prefix;
+    size_t prefix_length_in_bits;
+
+    if (!ParseCIDRBlock(raw, &ip_prefix, &prefix_length_in_bits))
+      return false;
+
+    rules_.push_back(
+        new BypassIPBlockRule(raw, scheme, ip_prefix, prefix_length_in_bits));
+
+    return true;
+  }
+
+  // Check if we have an <ip-address>[:port] input. We need to treat this
+  // separately since the IP literal may not be in a canonical form.
+  std::string host;
+  int port;
+  if (ParseHostAndPort(raw, &host, &port)) {
+    if (IsIPAddress(host)) {
+      // Canonicalize the IP literal before adding it as a string pattern.
+      GURL tmp_url("http://" + host);
+      return AddRuleForHostname(scheme, tmp_url.host(), port);
+    }
+  }
+
+  // Otherwise assume we have <hostname-pattern>[:port].
+  std::string::size_type pos_colon = raw.rfind(':');
+  host = raw;
+  port = -1;
+  if (pos_colon != std::string::npos) {
+    if (!base::StringToInt(base::StringPiece(raw.begin() + pos_colon + 1,
+                                             raw.end()),
+                           &port) ||
+        (port < 0 || port > 0xFFFF)) {
+      return false;  // Port was invalid.
+    }
+    raw = raw.substr(0, pos_colon);
+  }
+
+  // Special-case hostnames that begin with a period.
+  // For example, we remap ".google.com" --> "*.google.com".
+  if (StartsWithASCII(raw, ".", false))
+    raw = "*" + raw;
+
+  // If suffix matching was asked for, make sure the pattern starts with a
+  // wildcard.
+  if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false))
+    raw = "*" + raw;
+
+  return AddRuleForHostname(scheme, raw, port);
+}
+
+bool ProxyBypassRules::AddRuleFromStringInternalWithLogging(
+    const std::string& raw,
+    bool use_hostname_suffix_matching) {
+  return AddRuleFromStringInternal(raw, use_hostname_suffix_matching);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_bypass_rules.h b/src/net/proxy/proxy_bypass_rules.h
new file mode 100644
index 0000000..cfaacf0
--- /dev/null
+++ b/src/net/proxy/proxy_bypass_rules.h
@@ -0,0 +1,182 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_BYPASS_RULES_H_
+#define NET_PROXY_PROXY_BYPASS_RULES_H_
+
+#include <string>
+#include <vector>
+
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// ProxyBypassRules describes the set of URLs that should bypass the proxy
+// settings, as a list of rules. A URL is said to match the bypass rules
+// if it matches any one of these rules.
+class NET_EXPORT ProxyBypassRules {
+ public:
+  // Interface for an individual proxy bypass rule.
+  class NET_EXPORT Rule {
+   public:
+    Rule();
+    virtual ~Rule();
+
+    // Returns true if |url| matches the rule.
+    virtual bool Matches(const GURL& url) const = 0;
+
+    // Returns a string representation of this rule. This is used both for
+    // visualizing the rules, and also to test equality of a rules list.
+    virtual std::string ToString() const = 0;
+
+    // Creates a copy of this rule. (Caller is responsible for deleting it)
+    virtual Rule* Clone() const = 0;
+
+    bool Equals(const Rule& rule) const;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(Rule);
+  };
+
+  typedef std::vector<const Rule*> RuleList;
+
+  // Note: This class supports copy constructor and assignment.
+  ProxyBypassRules();
+  ProxyBypassRules(const ProxyBypassRules& rhs);
+  ~ProxyBypassRules();
+  ProxyBypassRules& operator=(const ProxyBypassRules& rhs);
+
+  // Returns the current list of rules. The rules list contains pointers
+  // which are owned by this class, callers should NOT keep references
+  // or delete them.
+  const RuleList& rules() const { return rules_; }
+
+  // Returns true if |url| matches any of the proxy bypass rules.
+  bool Matches(const GURL& url) const;
+
+  // Returns true if |*this| is equal to |other|; in other words, whether they
+  // describe the same set of rules.
+  bool Equals(const ProxyBypassRules& other) const;
+
+  // Initializes the list of rules by parsing the string |raw|. |raw| is a
+  // comma separated list of rules. See AddRuleFromString() to see the list
+  // of supported formats.
+  void ParseFromString(const std::string& raw);
+
+  // This is a variant of ParseFromString, which interprets hostname patterns
+  // as suffix tests rather than hostname tests (so "google.com" would actually
+  // match "*google.com"). This is only currently used for the linux no_proxy
+  // evironment variable. It is less flexible, since with the suffix matching
+  // format you can't match an individual host.
+  // NOTE: Use ParseFromString() unless you truly need this behavior.
+  void ParseFromStringUsingSuffixMatching(const std::string& raw);
+
+  // Adds a rule that matches a URL when all of the following are true:
+  //  (a) The URL's scheme matches |optional_scheme|, if
+  //      |!optional_scheme.empty()|
+  //  (b) The URL's hostname matches |hostname_pattern|.
+  //  (c) The URL's (effective) port number matches |optional_port| if
+  //      |optional_port != -1|
+  // Returns true if the rule was successfully added.
+  bool AddRuleForHostname(const std::string& optional_scheme,
+                          const std::string& hostname_pattern,
+                          int optional_port);
+
+  // Adds a rule that bypasses all "local" hostnames.
+  // This matches IE's interpretation of the
+  // "Bypass proxy server for local addresses" settings checkbox. Fully
+  // qualified domain names or IP addresses are considered non-local,
+  // regardless of what they map to (except for the loopback addresses).
+  void AddRuleToBypassLocal();
+
+  // Adds a rule given by the string |raw|. The format of |raw| can be any of
+  // the following:
+  //
+  // (1) [ URL_SCHEME "://" ] HOSTNAME_PATTERN [ ":" <port> ]
+  //
+  //   Match all hostnames that match the pattern HOSTNAME_PATTERN.
+  //
+  //   Examples:
+  //     "foobar.com", "*foobar.com", "*.foobar.com", "*foobar.com:99",
+  //     "https://x.*.y.com:99"
+  //
+  // (2) "." HOSTNAME_SUFFIX_PATTERN [ ":" PORT ]
+  //
+  //   Match a particular domain suffix.
+  //
+  //   Examples:
+  //     ".google.com", ".com", "http://.google.com"
+  //
+  // (3) [ SCHEME "://" ] IP_LITERAL [ ":" PORT ]
+  //
+  //   Match URLs which are IP address literals.
+  //
+  //   Conceptually this is the similar to (1), but with special cases
+  //   to handle IP literal canonicalization. For example matching
+  //   on "[0:0:0::1]" would be the same as matching on "[::1]" since
+  //   the IPv6 canonicalization is done internally.
+  //
+  //   Examples:
+  //     "127.0.1", "[0:0::1]", "[::1]", "http://[::1]:99"
+  //
+  // (4)  IP_LITERAL "/" PREFIX_LENGHT_IN_BITS
+  //
+  //   Match any URL that is to an IP literal that falls between the
+  //   given range. IP range is specified using CIDR notation.
+  //
+  //   Examples:
+  //     "192.168.1.1/16", "fefe:13::abc/33".
+  //
+  // (5)  "<local>"
+  //
+  //   Match local addresses. The meaning of "<local>" is whether the
+  //   host matches one of: "127.0.0.1", "::1", "localhost".
+  //
+  // See the unit-tests for more examples.
+  //
+  // Returns true if the rule was successfully added.
+  //
+  // TODO(eroman): support IPv6 literals without brackets.
+  //
+  bool AddRuleFromString(const std::string& raw);
+
+  // This is a variant of AddFromString, which interprets hostname patterns as
+  // suffix tests rather than hostname tests (so "google.com" would actually
+  // match "*google.com"). This is used for KDE which interprets every rule as
+  // a suffix test. It is less flexible, since with the suffix matching format
+  // you can't match an individual host.
+  //
+  // Returns true if the rule was successfully added.
+  //
+  // NOTE: Use AddRuleFromString() unless you truly need this behavior.
+  bool AddRuleFromStringUsingSuffixMatching(const std::string& raw);
+
+  // Converts the rules to string representation. Inverse operation to
+  // ParseFromString().
+  std::string ToString() const;
+
+  // Removes all the rules.
+  void Clear();
+
+  // Sets |*this| to |other|.
+  void AssignFrom(const ProxyBypassRules& other);
+
+ private:
+  // The following are variants of ParseFromString() and AddRuleFromString(),
+  // which additionally prefix hostname patterns with a wildcard if
+  // |use_hostname_suffix_matching| was true.
+  void ParseFromStringInternal(const std::string& raw,
+                               bool use_hostname_suffix_matching);
+  bool AddRuleFromStringInternal(const std::string& raw,
+                                 bool use_hostname_suffix_matching);
+  bool AddRuleFromStringInternalWithLogging(const std::string& raw,
+                                            bool use_hostname_suffix_matching);
+
+  RuleList rules_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_BYPASS_RULES_H_
diff --git a/src/net/proxy/proxy_bypass_rules_unittest.cc b/src/net/proxy/proxy_bypass_rules_unittest.cc
new file mode 100644
index 0000000..5b6ce04
--- /dev/null
+++ b/src/net/proxy/proxy_bypass_rules_unittest.cc
@@ -0,0 +1,315 @@
+// Copyright (c) 2010 The Chromium Authors. 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/proxy/proxy_bypass_rules.h"
+
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(ProxyBypassRulesTest, ParseAndMatchBasicHost) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("wWw.gOogle.com");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("www.google.com", rules.rules()[0]->ToString());
+
+  // All of these match; port, scheme, and non-hostname components don't
+  // matter.
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:99")));
+  EXPECT_TRUE(rules.Matches(GURL("https://www.google.com:81")));
+
+  // Must be a strict host match to work.
+  EXPECT_FALSE(rules.Matches(GURL("http://foo.www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://xxx.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.baz.org")));
+}
+
+TEST(ProxyBypassRulesTest, ParseAndMatchBasicDomain) {
+  ProxyBypassRules rules;
+  rules.ParseFromString(".gOOgle.com");
+  ASSERT_EQ(1u, rules.rules().size());
+  // Note that we inferred this was an "ends with" test.
+  EXPECT_EQ("*.google.com", rules.rules()[0]->ToString());
+
+  // All of these match; port, scheme, and non-hostname components don't
+  // matter.
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:99")));
+  EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:81")));
+  EXPECT_TRUE(rules.Matches(GURL("http://foo.google.com/x/y?q")));
+  EXPECT_TRUE(rules.Matches(GURL("http://foo:bar@baz.google.com#x")));
+
+  // Must be a strict "ends with" to work.
+  EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://foo.google.com.baz.org")));
+}
+
+TEST(ProxyBypassRulesTest, ParseAndMatchBasicDomainWithPort) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("*.GOOGLE.com:80");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("*.google.com:80", rules.rules()[0]->ToString());
+
+  // All of these match; scheme, and non-hostname components don't matter.
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:80")));
+  EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:80?x")));
+
+  // Must be a strict "ends with" to work.
+  EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://foo.google.com.baz.org")));
+
+  // The ports must match.
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com:90")));
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, MatchAll) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("*");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("*", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_TRUE(rules.Matches(GURL("ftp://www.foobar.com:99")));
+  EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:80?x")));
+}
+
+TEST(ProxyBypassRulesTest, WildcardAtStart) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("*.org:443");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("*.org:443", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.org:443")));
+  EXPECT_TRUE(rules.Matches(GURL("https://www.google.org")));
+
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.org")));
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.org.com")));
+}
+
+TEST(ProxyBypassRulesTest, IPV4Address) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("192.168.1.1");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("192.168.1.1", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1")));
+  EXPECT_TRUE(rules.Matches(GURL("https://192.168.1.1:90")));
+
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1")));
+}
+
+TEST(ProxyBypassRulesTest, IPV4AddressWithPort) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("192.168.1.1:33");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("192.168.1.1:33", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1:33")));
+
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://192.168.1.1")));
+  EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1:33")));
+}
+
+TEST(ProxyBypassRulesTest, IPV6Address) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("[3ffe:2a00:100:7031:0:0::1]");
+  ASSERT_EQ(1u, rules.rules().size());
+  // Note that we canonicalized the IP address.
+  EXPECT_EQ("[3ffe:2a00:100:7031::1]", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]")));
+  EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]:33")));
+
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1:33")));
+}
+
+TEST(ProxyBypassRulesTest, IPV6AddressWithPort) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("[3ffe:2a00:100:7031::1]:33");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("[3ffe:2a00:100:7031::1]:33", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]:33")));
+
+  EXPECT_FALSE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]")));
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, HTTPOnly) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("http://www.google.com");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("http://www.google.com", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com/foo")));
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com:99")));
+
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("ftp://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://foo.www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.org")));
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, HTTPOnlyWithWildcard) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("http://*www.google.com");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("http://*www.google.com", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com/foo")));
+  EXPECT_TRUE(rules.Matches(GURL("http://www.google.com:99")));
+  EXPECT_TRUE(rules.Matches(GURL("http://foo.www.google.com")));
+
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("ftp://www.google.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.org")));
+  EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, UseSuffixMatching) {
+  ProxyBypassRules rules;
+  rules.ParseFromStringUsingSuffixMatching(
+      "foo1.com, .foo2.com, 192.168.1.1, "
+      "*foobar.com:80, *.foo, http://baz, <local>");
+  ASSERT_EQ(7u, rules.rules().size());
+  EXPECT_EQ("*foo1.com", rules.rules()[0]->ToString());
+  EXPECT_EQ("*.foo2.com", rules.rules()[1]->ToString());
+  EXPECT_EQ("192.168.1.1", rules.rules()[2]->ToString());
+  EXPECT_EQ("*foobar.com:80", rules.rules()[3]->ToString());
+  EXPECT_EQ("*.foo", rules.rules()[4]->ToString());
+  EXPECT_EQ("http://*baz", rules.rules()[5]->ToString());
+  EXPECT_EQ("<local>", rules.rules()[6]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://foo1.com")));
+  EXPECT_TRUE(rules.Matches(GURL("http://aaafoo1.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://aaafoo1.com.net")));
+}
+
+TEST(ProxyBypassRulesTest, MultipleRules) {
+  ProxyBypassRules rules;
+  rules.ParseFromString(".google.com , .foobar.com:30");
+  ASSERT_EQ(2u, rules.rules().size());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://baz.google.com:40")));
+  EXPECT_FALSE(rules.Matches(GURL("http://google.com:40")));
+  EXPECT_TRUE(rules.Matches(GURL("http://bar.foobar.com:30")));
+  EXPECT_FALSE(rules.Matches(GURL("http://bar.foobar.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://bar.foobar.com:33")));
+}
+
+TEST(ProxyBypassRulesTest, BadInputs) {
+  ProxyBypassRules rules;
+  EXPECT_FALSE(rules.AddRuleFromString("://"));
+  EXPECT_FALSE(rules.AddRuleFromString("  "));
+  EXPECT_FALSE(rules.AddRuleFromString("http://"));
+  EXPECT_FALSE(rules.AddRuleFromString("*.foo.com:-34"));
+  EXPECT_EQ(0u, rules.rules().size());
+}
+
+TEST(ProxyBypassRulesTest, Equals) {
+  ProxyBypassRules rules1;
+  ProxyBypassRules rules2;
+
+  rules1.ParseFromString("foo1.com, .foo2.com");
+  rules2.ParseFromString("foo1.com,.FOo2.com");
+
+  EXPECT_TRUE(rules1.Equals(rules2));
+  EXPECT_TRUE(rules2.Equals(rules1));
+
+  rules1.ParseFromString(".foo2.com");
+  rules2.ParseFromString("foo1.com,.FOo2.com");
+
+  EXPECT_FALSE(rules1.Equals(rules2));
+  EXPECT_FALSE(rules2.Equals(rules1));
+}
+
+TEST(ProxyBypassRulesTest, BypassLocalNames) {
+  const struct {
+    const char* url;
+    bool expected_is_local;
+  } tests[] = {
+    // Single-component hostnames are considered local.
+    {"http://localhost/x", true},
+    {"http://www", true},
+
+    // IPv4 loopback interface.
+    {"http://127.0.0.1/x", true},
+    {"http://127.0.0.1:80/x", true},
+
+    // IPv6 loopback interface.
+    {"http://[::1]:80/x", true},
+    {"http://[0:0::1]:6233/x", true},
+    {"http://[0:0:0:0:0:0:0:1]/x", true},
+
+    // Non-local URLs.
+    {"http://foo.com/", false},
+    {"http://localhost.i/", false},
+    {"http://www.google.com/", false},
+    {"http://192.168.0.1/", false},
+
+    // Try with different protocols.
+    {"ftp://127.0.0.1/x", true},
+    {"ftp://foobar.com/x", false},
+
+    // This is a bit of a gray-area, but GURL does not strip trailing dots
+    // in host-names, so the following are considered non-local.
+    {"http://www./x", false},
+    {"http://localhost./x", false},
+  };
+
+  ProxyBypassRules rules;
+  rules.ParseFromString("<local>");
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    SCOPED_TRACE(base::StringPrintf(
+        "Test[%d]: %s", static_cast<int>(i), tests[i].url));
+    EXPECT_EQ(tests[i].expected_is_local, rules.Matches(GURL(tests[i].url)));
+  }
+}
+
+TEST(ProxyBypassRulesTest, ParseAndMatchCIDR_IPv4) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("192.168.1.1/16");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("192.168.1.1/16", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1")));
+  EXPECT_TRUE(rules.Matches(GURL("ftp://192.168.4.4")));
+  EXPECT_TRUE(rules.Matches(GURL("https://192.168.0.0:81")));
+  EXPECT_TRUE(rules.Matches(GURL("http://[::ffff:192.168.11.11]")));
+
+  EXPECT_FALSE(rules.Matches(GURL("http://foobar.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://192.169.1.1")));
+  EXPECT_FALSE(rules.Matches(GURL("http://xxx.192.168.1.1")));
+  EXPECT_FALSE(rules.Matches(GURL("http://192.168.1.1.xx")));
+}
+
+TEST(ProxyBypassRulesTest, ParseAndMatchCIDR_IPv6) {
+  ProxyBypassRules rules;
+  rules.ParseFromString("a:b:c:d::/48");
+  ASSERT_EQ(1u, rules.rules().size());
+  EXPECT_EQ("a:b:c:d::/48", rules.rules()[0]->ToString());
+
+  EXPECT_TRUE(rules.Matches(GURL("http://[A:b:C:9::]")));
+  EXPECT_FALSE(rules.Matches(GURL("http://foobar.com")));
+  EXPECT_FALSE(rules.Matches(GURL("http://192.169.1.1")));
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config.cc b/src/net/proxy/proxy_config.cc
new file mode 100644
index 0000000..12acc5a
--- /dev/null
+++ b/src/net/proxy/proxy_config.cc
@@ -0,0 +1,261 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_config.h"
+
+#include "base/logging.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "base/values.h"
+#include "net/proxy/proxy_info.h"
+
+namespace net {
+
+namespace {
+
+// If |proxy| is valid, sets it in |dict| under the key |name|.
+void AddProxyToValue(const char* name,
+                     const ProxyServer& proxy,
+                     DictionaryValue* dict) {
+  if (proxy.is_valid())
+    dict->SetString(name, proxy.ToURI());
+}
+
+}  // namespace
+
+ProxyConfig::ProxyRules::ProxyRules()
+    : reverse_bypass(false),
+      type(TYPE_NO_RULES) {
+}
+
+ProxyConfig::ProxyRules::~ProxyRules() {
+}
+
+void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const {
+  if (empty()) {
+    result->UseDirect();
+    return;
+  }
+
+  bool bypass_proxy = bypass_rules.Matches(url);
+  if (reverse_bypass)
+    bypass_proxy = !bypass_proxy;
+  if (bypass_proxy) {
+    result->UseDirectWithBypassedProxy();
+    return;
+  }
+
+  switch (type) {
+    case ProxyRules::TYPE_SINGLE_PROXY: {
+      result->UseProxyServer(single_proxy);
+      return;
+    }
+    case ProxyRules::TYPE_PROXY_PER_SCHEME: {
+      const ProxyServer* entry = MapUrlSchemeToProxy(url.scheme());
+      if (entry) {
+        result->UseProxyServer(*entry);
+      } else {
+        // We failed to find a matching proxy server for the current URL
+        // scheme. Default to direct.
+        result->UseDirect();
+      }
+      return;
+    }
+    default: {
+      result->UseDirect();
+      NOTREACHED();
+      return;
+    }
+  }
+}
+
+void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
+  // Reset.
+  type = TYPE_NO_RULES;
+  single_proxy = ProxyServer();
+  proxy_for_http = ProxyServer();
+  proxy_for_https = ProxyServer();
+  proxy_for_ftp = ProxyServer();
+  fallback_proxy = ProxyServer();
+
+  StringTokenizer proxy_server_list(proxy_rules, ";");
+  while (proxy_server_list.GetNext()) {
+    StringTokenizer proxy_server_for_scheme(
+        proxy_server_list.token_begin(), proxy_server_list.token_end(), "=");
+
+    while (proxy_server_for_scheme.GetNext()) {
+      std::string url_scheme = proxy_server_for_scheme.token();
+
+      // If we fail to get the proxy server here, it means that
+      // this is a regular proxy server configuration, i.e. proxies
+      // are not configured per protocol.
+      if (!proxy_server_for_scheme.GetNext()) {
+        if (type == TYPE_PROXY_PER_SCHEME)
+          continue;  // Unexpected.
+        single_proxy = ProxyServer::FromURI(url_scheme,
+                                            ProxyServer::SCHEME_HTTP);
+        type = TYPE_SINGLE_PROXY;
+        return;
+      }
+
+      // Trim whitespace off the url scheme.
+      TrimWhitespaceASCII(url_scheme, TRIM_ALL, &url_scheme);
+
+      // Add it to the per-scheme mappings (if supported scheme).
+      type = TYPE_PROXY_PER_SCHEME;
+      ProxyServer* entry = MapUrlSchemeToProxyNoFallback(url_scheme);
+      ProxyServer::Scheme default_scheme = ProxyServer::SCHEME_HTTP;
+
+      // socks=XXX is inconsistent with the other formats, since "socks"
+      // is not a URL scheme. Rather this means "for everything else, send
+      // it to the SOCKS proxy server XXX".
+      if (url_scheme == "socks") {
+        DCHECK(!entry);
+        entry = &fallback_proxy;
+        default_scheme = ProxyServer::SCHEME_SOCKS4;
+      }
+
+      if (entry) {
+        *entry = ProxyServer::FromURI(proxy_server_for_scheme.token(),
+                                      default_scheme);
+      }
+    }
+  }
+}
+
+const ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxy(
+    const std::string& url_scheme) const {
+  const ProxyServer* proxy_server =
+      const_cast<ProxyRules*>(this)->MapUrlSchemeToProxyNoFallback(url_scheme);
+  if (proxy_server && proxy_server->is_valid())
+    return proxy_server;
+  if (fallback_proxy.is_valid())
+    return &fallback_proxy;
+  return NULL;  // No mapping for this scheme. Use direct.
+}
+
+bool ProxyConfig::ProxyRules::Equals(const ProxyRules& other) const {
+  return type == other.type &&
+         single_proxy == other.single_proxy &&
+         proxy_for_http == other.proxy_for_http &&
+         proxy_for_https == other.proxy_for_https &&
+         proxy_for_ftp == other.proxy_for_ftp &&
+         fallback_proxy == other.fallback_proxy &&
+         bypass_rules.Equals(other.bypass_rules) &&
+         reverse_bypass == other.reverse_bypass;
+}
+
+ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxyNoFallback(
+    const std::string& scheme) {
+  DCHECK_EQ(TYPE_PROXY_PER_SCHEME, type);
+  if (scheme == "http")
+    return &proxy_for_http;
+  if (scheme == "https")
+    return &proxy_for_https;
+  if (scheme == "ftp")
+    return &proxy_for_ftp;
+  return NULL;  // No mapping for this scheme.
+}
+
+ProxyConfig::ProxyConfig()
+    : auto_detect_(false), pac_mandatory_(false),
+      source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID)  {
+}
+
+ProxyConfig::ProxyConfig(const ProxyConfig& config)
+    : auto_detect_(config.auto_detect_),
+      pac_url_(config.pac_url_),
+      pac_mandatory_(config.pac_mandatory_),
+      proxy_rules_(config.proxy_rules_),
+      source_(config.source_),
+      id_(config.id_) {
+}
+
+ProxyConfig::~ProxyConfig() {
+}
+
+ProxyConfig& ProxyConfig::operator=(const ProxyConfig& config) {
+  auto_detect_ = config.auto_detect_;
+  pac_url_ = config.pac_url_;
+  pac_mandatory_ = config.pac_mandatory_;
+  proxy_rules_ = config.proxy_rules_;
+  source_ = config.source_;
+  id_ = config.id_;
+  return *this;
+}
+
+bool ProxyConfig::Equals(const ProxyConfig& other) const {
+  // The two configs can have different IDs and sources.  We are just interested
+  // in if they have the same settings.
+  return auto_detect_ == other.auto_detect_ &&
+         pac_url_ == other.pac_url_ &&
+         pac_mandatory_ == other.pac_mandatory_ &&
+         proxy_rules_.Equals(other.proxy_rules());
+}
+
+bool ProxyConfig::HasAutomaticSettings() const {
+  return auto_detect_ || has_pac_url();
+}
+
+void ProxyConfig::ClearAutomaticSettings() {
+  auto_detect_ = false;
+  pac_url_ = GURL();
+}
+
+Value* ProxyConfig::ToValue() const {
+  DictionaryValue* dict = new DictionaryValue();
+
+  // Output the automatic settings.
+  if (auto_detect_)
+    dict->SetBoolean("auto_detect", auto_detect_);
+  if (has_pac_url()) {
+    dict->SetString("pac_url", pac_url_.possibly_invalid_spec());
+    if (pac_mandatory_)
+      dict->SetBoolean("pac_mandatory", pac_mandatory_);
+  }
+
+  // Output the manual settings.
+  if (proxy_rules_.type != ProxyRules::TYPE_NO_RULES) {
+    switch (proxy_rules_.type) {
+      case ProxyRules::TYPE_SINGLE_PROXY:
+        AddProxyToValue("single_proxy", proxy_rules_.single_proxy, dict);
+        break;
+      case ProxyRules::TYPE_PROXY_PER_SCHEME: {
+        DictionaryValue* dict2 = new DictionaryValue();
+        AddProxyToValue("http", proxy_rules_.proxy_for_http, dict2);
+        AddProxyToValue("https", proxy_rules_.proxy_for_https, dict2);
+        AddProxyToValue("ftp", proxy_rules_.proxy_for_ftp, dict2);
+        AddProxyToValue("fallback", proxy_rules_.fallback_proxy, dict2);
+        dict->Set("proxy_per_scheme", dict2);
+        break;
+      }
+      default:
+        NOTREACHED();
+    }
+
+    // Output the bypass rules.
+    const ProxyBypassRules& bypass = proxy_rules_.bypass_rules;
+    if (!bypass.rules().empty()) {
+      if (proxy_rules_.reverse_bypass)
+        dict->SetBoolean("reverse_bypass", true);
+
+      ListValue* list = new ListValue();
+
+      for (ProxyBypassRules::RuleList::const_iterator it =
+              bypass.rules().begin();
+           it != bypass.rules().end(); ++it) {
+        list->Append(Value::CreateStringValue((*it)->ToString()));
+      }
+
+      dict->Set("bypass_list", list);
+    }
+  }
+
+  // Output the source.
+  dict->SetString("source", ProxyConfigSourceToString(source_));
+
+  return dict;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config.h b/src/net/proxy/proxy_config.h
new file mode 100644
index 0000000..29619df
--- /dev/null
+++ b/src/net/proxy/proxy_config.h
@@ -0,0 +1,227 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_PROXY_CONFIG_H_
+#define NET_PROXY_PROXY_CONFIG_H_
+
+#include <string>
+
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_bypass_rules.h"
+#include "net/proxy/proxy_config_source.h"
+#include "net/proxy/proxy_server.h"
+
+namespace base {
+class Value;
+}
+
+namespace net {
+
+class ProxyInfo;
+
+// ProxyConfig describes a user's proxy settings.
+//
+// There are two categories of proxy settings:
+//   (1) Automatic (indicates the methods to obtain a PAC script)
+//   (2) Manual (simple set of proxy servers per scheme, and bypass patterns)
+//
+// When both automatic and manual settings are specified, the Automatic ones
+// take precedence over the manual ones.
+//
+// For more details see:
+// http://www.chromium.org/developers/design-documents/proxy-settings-fallback
+class NET_EXPORT ProxyConfig {
+ public:
+  // ProxyRules describes the "manual" proxy settings.
+  // TODO(eroman): Turn this into a class.
+  struct NET_EXPORT ProxyRules {
+    enum Type {
+      TYPE_NO_RULES,
+      TYPE_SINGLE_PROXY,
+      TYPE_PROXY_PER_SCHEME,
+    };
+
+    // Note that the default of TYPE_NO_RULES results in direct connections
+    // being made when using this ProxyConfig.
+    ProxyRules();
+    ~ProxyRules();
+
+    bool empty() const {
+      return type == TYPE_NO_RULES;
+    }
+
+    // Sets |result| with the proxy to use for |url| based on the current rules.
+    void Apply(const GURL& url, ProxyInfo* result) const;
+
+    // Parses the rules from a string, indicating which proxies to use.
+    //
+    //   proxy-uri = [<proxy-scheme>"://"]<proxy-host>[":"<proxy-port>]
+    //
+    // If the proxy to use depends on the scheme of the URL, can instead specify
+    // a semicolon separated list of:
+    //
+    //   <url-scheme>"="<proxy-uri>
+    //
+    // For example:
+    //   "http=foopy:80;ftp=foopy2"  -- use HTTP proxy "foopy:80" for http://
+    //                                  URLs, and HTTP proxy "foopy2:80" for
+    //                                  ftp:// URLs.
+    //   "foopy:80"                  -- use HTTP proxy "foopy:80" for all URLs.
+    //   "socks4://foopy"            -- use SOCKS v4 proxy "foopy:1080" for all
+    //                                  URLs.
+    void ParseFromString(const std::string& proxy_rules);
+
+    // Returns one of {&proxy_for_http, &proxy_for_https, &proxy_for_ftp,
+    // &fallback_proxy}, or NULL if there is no proxy to use.
+    // Should only call this if the type is TYPE_PROXY_PER_SCHEME.
+    const ProxyServer* MapUrlSchemeToProxy(const std::string& url_scheme) const;
+
+    // Returns true if |*this| describes the same configuration as |other|.
+    bool Equals(const ProxyRules& other) const;
+
+    // Exceptions for when not to use a proxy.
+    ProxyBypassRules bypass_rules;
+
+    // Reverse the meaning of |bypass_rules|.
+    bool reverse_bypass;
+
+    Type type;
+
+    // Set if |type| is TYPE_SINGLE_PROXY.
+    ProxyServer single_proxy;
+
+    // Set if |type| is TYPE_PROXY_PER_SCHEME.
+    ProxyServer proxy_for_http;
+    ProxyServer proxy_for_https;
+    ProxyServer proxy_for_ftp;
+
+    // Used when there isn't a more specific per-scheme proxy server.
+    ProxyServer fallback_proxy;
+
+   private:
+    // Returns one of {&proxy_for_http, &proxy_for_https, &proxy_for_ftp}
+    // or NULL if it is a scheme that we don't have a mapping
+    // for. Should only call this if the type is TYPE_PROXY_PER_SCHEME.
+    ProxyServer* MapUrlSchemeToProxyNoFallback(const std::string& scheme);
+  };
+
+  typedef int ID;
+
+  // Indicates an invalid proxy config.
+  static const ID kInvalidConfigID = 0;
+
+  ProxyConfig();
+  ProxyConfig(const ProxyConfig& config);
+  ~ProxyConfig();
+  ProxyConfig& operator=(const ProxyConfig& config);
+
+  // Used to numerically identify this configuration.
+  ID id() const { return id_; }
+  void set_id(ID id) { id_ = id; }
+  bool is_valid() const { return id_ != kInvalidConfigID; }
+
+  // Returns true if the given config is equivalent to this config.  The
+  // comparison ignores differences in |id()| and |source()|.
+  bool Equals(const ProxyConfig& other) const;
+
+  // Returns true if this config contains any "automatic" settings. See the
+  // class description for what that means.
+  bool HasAutomaticSettings() const;
+
+  void ClearAutomaticSettings();
+
+  // Creates a Value dump of this configuration. The caller is responsible for
+  // deleting the returned value.
+  base::Value* ToValue() const;
+
+  ProxyRules& proxy_rules() {
+    return proxy_rules_;
+  }
+
+  const ProxyRules& proxy_rules() const {
+    return proxy_rules_;
+  }
+
+  void set_pac_url(const GURL& url) {
+    pac_url_ = url;
+  }
+
+  const GURL& pac_url() const {
+    return pac_url_;
+  }
+
+  void set_pac_mandatory(bool enable_pac_mandatory) {
+    pac_mandatory_ = enable_pac_mandatory;
+  }
+
+  bool pac_mandatory() const {
+    return pac_mandatory_;
+  }
+
+  bool has_pac_url() const {
+    return pac_url_.is_valid();
+  }
+
+  void set_auto_detect(bool enable_auto_detect) {
+    auto_detect_ = enable_auto_detect;
+  }
+
+  bool auto_detect() const {
+    return auto_detect_;
+  }
+
+  void set_source(ProxyConfigSource source) {
+    source_ = source;
+  }
+
+  ProxyConfigSource source() const {
+    return source_;
+  }
+
+  // Helpers to construct some common proxy configurations.
+
+  static ProxyConfig CreateDirect() {
+    return ProxyConfig();
+  }
+
+  static ProxyConfig CreateAutoDetect() {
+    ProxyConfig config;
+    config.set_auto_detect(true);
+    return config;
+  }
+
+  static ProxyConfig CreateFromCustomPacURL(const GURL& pac_url) {
+    ProxyConfig config;
+    config.set_pac_url(pac_url);
+    // By default fall back to direct connection in case PAC script fails.
+    config.set_pac_mandatory(false);
+    return config;
+  }
+
+ private:
+  // True if the proxy configuration should be auto-detected.
+  bool auto_detect_;
+
+  // If non-empty, indicates the URL of the proxy auto-config file to use.
+  GURL pac_url_;
+
+  // If true, blocks all traffic in case fetching the pac script from |pac_url_|
+  // fails. Only valid if |pac_url_| is non-empty.
+  bool pac_mandatory_;
+
+  // Manual proxy settings.
+  ProxyRules proxy_rules_;
+
+  // Source of proxy settings.
+  ProxyConfigSource source_;
+
+  ID id_;
+};
+
+}  // namespace net
+
+
+
+#endif  // NET_PROXY_PROXY_CONFIG_H_
diff --git a/src/net/proxy/proxy_config_service.h b/src/net/proxy/proxy_config_service.h
new file mode 100644
index 0000000..5e14995
--- /dev/null
+++ b/src/net/proxy/proxy_config_service.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_H_
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+class ProxyConfig;
+
+// Service for watching when the proxy settings have changed.
+class NET_EXPORT ProxyConfigService {
+ public:
+  // Indicates whether proxy configuration is valid, and if not, why.
+  enum ConfigAvailability {
+    // Configuration is pending, observers will be notified later.
+    CONFIG_PENDING,
+    // Configuration is present and valid.
+    CONFIG_VALID,
+    // No configuration is set.
+    CONFIG_UNSET
+  };
+
+  // Observer for being notified when the proxy settings have changed.
+  class NET_EXPORT Observer {
+   public:
+    virtual ~Observer() {}
+    // Notification callback that should be invoked by ProxyConfigService
+    // implementors whenever the configuration changes. |availability| indicates
+    // the new availability status and can be CONFIG_UNSET or CONFIG_VALID (in
+    // which case |config| contains the configuration). Implementors must not
+    // pass CONFIG_PENDING.
+    virtual void OnProxyConfigChanged(const ProxyConfig& config,
+                                      ConfigAvailability availability) = 0;
+  };
+
+  virtual ~ProxyConfigService() {}
+
+  // Adds/Removes an observer that will be called whenever the proxy
+  // configuration has changed.
+  virtual void AddObserver(Observer* observer) = 0;
+  virtual void RemoveObserver(Observer* observer) = 0;
+
+  // Gets the most recent availability status. If a configuration is present,
+  // the proxy configuration is written to |config| and CONFIG_VALID is
+  // returned. Returns CONFIG_PENDING if it is not available yet. In this case,
+  // it is guaranteed that subscribed observers will be notified of a change at
+  // some point in the future once the configuration is available.
+  // Note that to avoid re-entrancy problems, implementations should not
+  // dispatch any change notifications from within this function.
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) = 0;
+
+  // ProxyService will call this periodically during periods of activity.
+  // It can be used as a signal for polling-based implementations.
+  //
+  // Note that this is purely used as an optimization -- polling
+  // implementations could simply set a global timer that goes off every
+  // X seconds at which point they check for changes. However that has
+  // the disadvantage of doing continuous work even during idle periods.
+  virtual void OnLazyPoll() {}
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_H_
diff --git a/src/net/proxy/proxy_config_service_android.cc b/src/net/proxy/proxy_config_service_android.cc
new file mode 100644
index 0000000..f48c366
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_android.cc
@@ -0,0 +1,338 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_config_service_android.h"
+
+#include <sys/system_properties.h>
+
+#include "base/android/jni_string.h"
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list.h"
+#include "base/sequenced_task_runner.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "googleurl/src/url_parse.h"
+#include "jni/ProxyChangeListener_jni.h"
+#include "net/base/host_port_pair.h"
+#include "net/proxy/proxy_config.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ConvertJavaStringToUTF8;
+using base::android::CheckException;
+using base::android::ClearException;
+using base::android::ScopedJavaGlobalRef;
+
+namespace net {
+
+namespace {
+
+typedef ProxyConfigServiceAndroid::GetPropertyCallback GetPropertyCallback;
+
+// Returns whether the provided string was successfully converted to a port.
+bool ConvertStringToPort(const std::string& port, int* output) {
+  url_parse::Component component(0, port.size());
+  int result = url_parse::ParsePort(port.c_str(), component);
+  if (result == url_parse::PORT_INVALID ||
+      result == url_parse::PORT_UNSPECIFIED)
+    return false;
+  *output = result;
+  return true;
+}
+
+ProxyServer ConstructProxyServer(ProxyServer::Scheme scheme,
+                                 const std::string& proxy_host,
+                                 const std::string& proxy_port) {
+  DCHECK(!proxy_host.empty());
+  int port_as_int = 0;
+  if (proxy_port.empty())
+    port_as_int = ProxyServer::GetDefaultPortForScheme(scheme);
+  else if (!ConvertStringToPort(proxy_port, &port_as_int))
+    return ProxyServer();
+  DCHECK(port_as_int > 0);
+  return ProxyServer(
+      scheme,
+      HostPortPair(proxy_host, static_cast<uint16>(port_as_int)));
+}
+
+ProxyServer LookupProxy(const std::string& prefix,
+                        const GetPropertyCallback& get_property,
+                        ProxyServer::Scheme scheme) {
+  DCHECK(!prefix.empty());
+  std::string proxy_host = get_property.Run(prefix + ".proxyHost");
+  if (!proxy_host.empty()) {
+    std::string proxy_port = get_property.Run(prefix + ".proxyPort");
+    return ConstructProxyServer(scheme, proxy_host, proxy_port);
+  }
+  // Fall back to default proxy, if any.
+  proxy_host = get_property.Run("proxyHost");
+  if (!proxy_host.empty()) {
+    std::string proxy_port = get_property.Run("proxyPort");
+    return ConstructProxyServer(scheme, proxy_host, proxy_port);
+  }
+  return ProxyServer();
+}
+
+ProxyServer LookupSocksProxy(const GetPropertyCallback& get_property) {
+  std::string proxy_host = get_property.Run("socksProxyHost");
+  if (!proxy_host.empty()) {
+    std::string proxy_port = get_property.Run("socksProxyPort");
+    return ConstructProxyServer(ProxyServer::SCHEME_SOCKS5, proxy_host,
+                                proxy_port);
+  }
+  return ProxyServer();
+}
+
+void AddBypassRules(const std::string& scheme,
+                    const GetPropertyCallback& get_property,
+                    ProxyBypassRules* bypass_rules) {
+  // The format of a hostname pattern is a list of hostnames that are separated
+  // by | and that use * as a wildcard. For example, setting the
+  // http.nonProxyHosts property to *.android.com|*.kernel.org will cause
+  // requests to http://developer.android.com to be made without a proxy.
+  std::string non_proxy_hosts =
+      get_property.Run(scheme + ".nonProxyHosts");
+  if (non_proxy_hosts.empty())
+    return;
+  StringTokenizer tokenizer(non_proxy_hosts, "|");
+  while (tokenizer.GetNext()) {
+    std::string token = tokenizer.token();
+    std::string pattern;
+    TrimWhitespaceASCII(token, TRIM_ALL, &pattern);
+    if (pattern.empty())
+      continue;
+    // '?' is not one of the specified pattern characters above.
+    DCHECK_EQ(std::string::npos, pattern.find('?'));
+    bypass_rules->AddRuleForHostname(scheme, pattern, -1);
+  }
+}
+
+// Returns true if a valid proxy was found.
+bool GetProxyRules(const GetPropertyCallback& get_property,
+                   ProxyConfig::ProxyRules* rules) {
+  // See libcore/luni/src/main/java/java/net/ProxySelectorImpl.java for the
+  // mostly equivalent Android implementation.  There is one intentional
+  // difference: by default Chromium uses the HTTP port (80) for HTTPS
+  // connections via proxy.  This default is identical on other platforms.
+  // On the opposite, Java spec suggests to use HTTPS port (443) by default (the
+  // default value of https.proxyPort).
+  rules->type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+  rules->proxy_for_http = LookupProxy("http", get_property,
+                                      ProxyServer::SCHEME_HTTP);
+  rules->proxy_for_https = LookupProxy("https", get_property,
+                                       ProxyServer::SCHEME_HTTP);
+  rules->proxy_for_ftp = LookupProxy("ftp", get_property,
+                                     ProxyServer::SCHEME_HTTP);
+  rules->fallback_proxy = LookupSocksProxy(get_property);
+  rules->bypass_rules.Clear();
+  AddBypassRules("ftp", get_property, &rules->bypass_rules);
+  AddBypassRules("http", get_property, &rules->bypass_rules);
+  AddBypassRules("https", get_property, &rules->bypass_rules);
+  return rules->proxy_for_http.is_valid() ||
+      rules->proxy_for_https.is_valid() ||
+      rules->proxy_for_ftp.is_valid() ||
+      rules->fallback_proxy.is_valid();
+};
+
+void GetLatestProxyConfigInternal(const GetPropertyCallback& get_property,
+                                  ProxyConfig* config) {
+  if (!GetProxyRules(get_property, &config->proxy_rules()))
+    *config = ProxyConfig::CreateDirect();
+}
+
+std::string GetJavaProperty(const std::string& property) {
+  // Use Java System.getProperty to get configuration information.
+  // TODO(pliard): Conversion to/from UTF8 ok here?
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString(env, property);
+  ScopedJavaLocalRef<jstring> result =
+      Java_ProxyChangeListener_getProperty(env, str.obj());
+  return result.is_null() ?
+      std::string() : ConvertJavaStringToUTF8(env, result.obj());
+}
+
+}  // namespace
+
+class ProxyConfigServiceAndroid::Delegate
+    : public base::RefCountedThreadSafe<Delegate> {
+ public:
+  Delegate(base::SequencedTaskRunner* network_task_runner,
+           base::SequencedTaskRunner* jni_task_runner,
+           const GetPropertyCallback& get_property_callback)
+      : ALLOW_THIS_IN_INITIALIZER_LIST(jni_delegate_(this)),
+        network_task_runner_(network_task_runner),
+        jni_task_runner_(jni_task_runner),
+        get_property_callback_(get_property_callback) {
+  }
+
+  void SetupJNI() {
+    DCHECK(OnJNIThread());
+    JNIEnv* env = AttachCurrentThread();
+    if (java_proxy_change_listener_.is_null()) {
+      java_proxy_change_listener_.Reset(
+          Java_ProxyChangeListener_create(
+              env, base::android::GetApplicationContext()));
+      CHECK(!java_proxy_change_listener_.is_null());
+    }
+    Java_ProxyChangeListener_start(
+        env,
+        java_proxy_change_listener_.obj(),
+        reinterpret_cast<jint>(&jni_delegate_));
+  }
+
+  void FetchInitialConfig() {
+    DCHECK(OnJNIThread());
+    ProxyConfig proxy_config;
+    GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
+    network_task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(&Delegate::SetNewConfigOnNetworkThread, this, proxy_config));
+  }
+
+  void Shutdown() {
+    if (OnJNIThread()) {
+      ShutdownOnJNIThread();
+    } else {
+      jni_task_runner_->PostTask(
+          FROM_HERE,
+          base::Bind(&Delegate::ShutdownOnJNIThread, this));
+    }
+  }
+
+  // Called only on the network thread.
+  void AddObserver(Observer* observer) {
+    DCHECK(OnNetworkThread());
+    observers_.AddObserver(observer);
+  }
+
+  void RemoveObserver(Observer* observer) {
+    DCHECK(OnNetworkThread());
+    observers_.RemoveObserver(observer);
+  }
+
+  ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) {
+    DCHECK(OnNetworkThread());
+    if (!config)
+      return ProxyConfigService::CONFIG_UNSET;
+    *config = proxy_config_;
+    return ProxyConfigService::CONFIG_VALID;
+  }
+
+  // Called on the JNI thread.
+  void ProxySettingsChanged() {
+    DCHECK(OnJNIThread());
+    ProxyConfig proxy_config;
+    GetLatestProxyConfigInternal(get_property_callback_, &proxy_config);
+    network_task_runner_->PostTask(
+        FROM_HERE,
+        base::Bind(
+            &Delegate::SetNewConfigOnNetworkThread, this, proxy_config));
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<Delegate>;
+
+  class JNIDelegateImpl : public ProxyConfigServiceAndroid::JNIDelegate {
+   public:
+    explicit JNIDelegateImpl(Delegate* delegate) : delegate_(delegate) {}
+
+    // ProxyConfigServiceAndroid::JNIDelegate overrides.
+    virtual void ProxySettingsChanged(JNIEnv*, jobject) OVERRIDE {
+      delegate_->ProxySettingsChanged();
+    }
+
+   private:
+    Delegate* const delegate_;
+  };
+
+  virtual ~Delegate() {}
+
+  void ShutdownOnJNIThread() {
+    if (java_proxy_change_listener_.is_null())
+      return;
+    JNIEnv* env = AttachCurrentThread();
+    Java_ProxyChangeListener_stop(env, java_proxy_change_listener_.obj());
+  }
+
+  // Called on the network thread.
+  void SetNewConfigOnNetworkThread(const ProxyConfig& proxy_config) {
+    DCHECK(OnNetworkThread());
+    proxy_config_ = proxy_config;
+    FOR_EACH_OBSERVER(Observer, observers_,
+                      OnProxyConfigChanged(proxy_config,
+                                           ProxyConfigService::CONFIG_VALID));
+  }
+
+  bool OnJNIThread() const {
+    return jni_task_runner_->RunsTasksOnCurrentThread();
+  }
+
+  bool OnNetworkThread() const {
+    return network_task_runner_->RunsTasksOnCurrentThread();
+  }
+
+  ScopedJavaGlobalRef<jobject> java_proxy_change_listener_;
+
+  JNIDelegateImpl jni_delegate_;
+  ObserverList<Observer> observers_;
+  scoped_refptr<base::SequencedTaskRunner> network_task_runner_;
+  scoped_refptr<base::SequencedTaskRunner> jni_task_runner_;
+  GetPropertyCallback get_property_callback_;
+  ProxyConfig proxy_config_;
+
+  DISALLOW_COPY_AND_ASSIGN(Delegate);
+};
+
+ProxyConfigServiceAndroid::ProxyConfigServiceAndroid(
+    base::SequencedTaskRunner* network_task_runner,
+    base::SequencedTaskRunner* jni_task_runner)
+    : delegate_(new Delegate(
+        network_task_runner, jni_task_runner, base::Bind(&GetJavaProperty))) {
+  delegate_->SetupJNI();
+  delegate_->FetchInitialConfig();
+}
+
+ProxyConfigServiceAndroid::~ProxyConfigServiceAndroid() {
+  delegate_->Shutdown();
+}
+
+// static
+bool ProxyConfigServiceAndroid::Register(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+void ProxyConfigServiceAndroid::AddObserver(Observer* observer) {
+  delegate_->AddObserver(observer);
+}
+
+void ProxyConfigServiceAndroid::RemoveObserver(Observer* observer) {
+  delegate_->RemoveObserver(observer);
+}
+
+ProxyConfigService::ConfigAvailability
+ProxyConfigServiceAndroid::GetLatestProxyConfig(ProxyConfig* config) {
+  return delegate_->GetLatestProxyConfig(config);
+}
+
+ProxyConfigServiceAndroid::ProxyConfigServiceAndroid(
+    base::SequencedTaskRunner* network_task_runner,
+    base::SequencedTaskRunner* jni_task_runner,
+    GetPropertyCallback get_property_callback)
+    : delegate_(new Delegate(
+        network_task_runner, jni_task_runner, get_property_callback)) {
+  delegate_->SetupJNI();
+  delegate_->FetchInitialConfig();
+}
+
+void ProxyConfigServiceAndroid::ProxySettingsChanged() {
+  delegate_->ProxySettingsChanged();
+}
+
+} // namespace net
diff --git a/src/net/proxy/proxy_config_service_android.h b/src/net/proxy/proxy_config_service_android.h
new file mode 100644
index 0000000..3ddbaeb
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_android.h
@@ -0,0 +1,79 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_ANDROID_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_ANDROID_H_
+
+#include <string>
+
+#include "base/android/jni_android.h"
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_config_service.h"
+
+namespace base {
+class SequencedTaskRunner;
+}
+
+namespace net {
+
+class ProxyConfig;
+
+class NET_EXPORT ProxyConfigServiceAndroid : public ProxyConfigService {
+ public:
+  // Callback that returns the value of the property identified by the provided
+  // key. If it was not found, an empty string is returned. Note that this
+  // interface does not let you distinguish an empty property from a
+  // non-existing property. This callback is invoked on the JNI thread.
+  typedef base::Callback<std::string (const std::string& property)>
+      GetPropertyCallback;
+
+  // Separate class whose instance is owned by the Delegate class implemented in
+  // the .cc file.
+  class JNIDelegate {
+   public:
+    virtual ~JNIDelegate() {}
+
+    // Called from Java (on JNI thread) to signal that the proxy settings have
+    // changed.
+    virtual void ProxySettingsChanged(JNIEnv*, jobject) = 0;
+  };
+
+  ProxyConfigServiceAndroid(base::SequencedTaskRunner* network_task_runner,
+                            base::SequencedTaskRunner* jni_task_runner);
+
+  virtual ~ProxyConfigServiceAndroid();
+
+  // Register JNI bindings.
+  static bool Register(JNIEnv* env);
+
+  // ProxyConfigService:
+  // Called only on the network thread.
+  virtual void AddObserver(Observer* observer) OVERRIDE;
+  virtual void RemoveObserver(Observer* observer) OVERRIDE;
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) OVERRIDE;
+
+ private:
+  friend class ProxyConfigServiceAndroidTestBase;
+  class Delegate;
+
+  // For tests.
+  ProxyConfigServiceAndroid(base::SequencedTaskRunner* network_task_runner,
+                            base::SequencedTaskRunner* jni_task_runner,
+                            GetPropertyCallback get_property_callback);
+
+  // For tests.
+  void ProxySettingsChanged();
+
+  scoped_refptr<Delegate> delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceAndroid);
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_CONFIG_SERVICE_ANDROID_H_
diff --git a/src/net/proxy/proxy_config_service_android_unittest.cc b/src/net/proxy/proxy_config_service_android_unittest.cc
new file mode 100644
index 0000000..b7bdb3e
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_android_unittest.cc
@@ -0,0 +1,353 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <map>
+#include <string>
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_android.h"
+#include "net/proxy/proxy_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+class TestObserver : public ProxyConfigService::Observer {
+ public:
+  TestObserver() : availability_(ProxyConfigService::CONFIG_UNSET) {}
+
+  // ProxyConfigService::Observer:
+  virtual void OnProxyConfigChanged(
+      const ProxyConfig& config,
+      ProxyConfigService::ConfigAvailability availability) OVERRIDE {
+    config_ = config;
+    availability_ = availability;
+  }
+
+  ProxyConfigService::ConfigAvailability availability() const {
+    return availability_;
+  }
+
+  const ProxyConfig& config() const {
+    return config_;
+  }
+
+ private:
+  ProxyConfig config_;
+  ProxyConfigService::ConfigAvailability availability_;
+};
+
+}  // namespace
+
+typedef std::map<std::string, std::string> StringMap;
+
+class ProxyConfigServiceAndroidTestBase : public testing::Test {
+ protected:
+  // Note that the current thread's message loop is initialized by the test
+  // suite (see net/base/net_test_suite.cc).
+  ProxyConfigServiceAndroidTestBase(const StringMap& initial_configuration)
+      : configuration_(initial_configuration),
+        message_loop_(MessageLoop::current()),
+        service_(
+            message_loop_->message_loop_proxy(),
+            message_loop_->message_loop_proxy(),
+            base::Bind(&ProxyConfigServiceAndroidTestBase::GetProperty,
+                       base::Unretained(this))) {}
+
+  virtual ~ProxyConfigServiceAndroidTestBase() {}
+
+  // testing::Test:
+  virtual void SetUp() OVERRIDE {
+    message_loop_->RunUntilIdle();
+    service_.AddObserver(&observer_);
+  }
+
+  virtual void TearDown() OVERRIDE {
+    service_.RemoveObserver(&observer_);
+  }
+
+  void ClearConfiguration() {
+    configuration_.clear();
+  }
+
+  void AddProperty(const std::string& key, const std::string& value) {
+    configuration_[key] = value;
+  }
+
+  std::string GetProperty(const std::string& key) {
+    StringMap::const_iterator it = configuration_.find(key);
+    if (it == configuration_.end())
+      return std::string();
+    return it->second;
+  }
+
+  void ProxySettingsChanged() {
+    service_.ProxySettingsChanged();
+    message_loop_->RunUntilIdle();
+  }
+
+  void TestMapping(const std::string& url, const std::string& expected) {
+    ProxyConfigService::ConfigAvailability availability;
+    ProxyConfig proxy_config;
+    availability = service_.GetLatestProxyConfig(&proxy_config);
+    EXPECT_EQ(ProxyConfigService::CONFIG_VALID, availability);
+    ProxyInfo proxy_info;
+    proxy_config.proxy_rules().Apply(GURL(url), &proxy_info);
+    EXPECT_EQ(expected, proxy_info.ToPacString());
+  }
+
+  StringMap configuration_;
+  TestObserver observer_;
+  MessageLoop* const message_loop_;
+  ProxyConfigServiceAndroid service_;
+};
+
+class ProxyConfigServiceAndroidTest : public ProxyConfigServiceAndroidTestBase {
+ public:
+  ProxyConfigServiceAndroidTest()
+      : ProxyConfigServiceAndroidTestBase(StringMap()) {}
+};
+
+class ProxyConfigServiceAndroidWithInitialConfigTest
+    : public ProxyConfigServiceAndroidTestBase {
+ public:
+  ProxyConfigServiceAndroidWithInitialConfigTest()
+      : ProxyConfigServiceAndroidTestBase(MakeInitialConfiguration()) {}
+
+ private:
+  StringMap MakeInitialConfiguration() {
+    StringMap initial_configuration;
+    initial_configuration["http.proxyHost"] = "httpproxy.com";
+    initial_configuration["http.proxyPort"] = "8080";
+    return initial_configuration;
+  }
+};
+
+TEST_F(ProxyConfigServiceAndroidTest, TestChangePropertiesNotification) {
+  // Set up a non-empty configuration
+  AddProperty("http.proxyHost", "localhost");
+  ProxySettingsChanged();
+  EXPECT_EQ(ProxyConfigService::CONFIG_VALID, observer_.availability());
+  EXPECT_FALSE(observer_.config().proxy_rules().empty());
+
+  // Set up an empty configuration
+  ClearConfiguration();
+  ProxySettingsChanged();
+  EXPECT_EQ(ProxyConfigService::CONFIG_VALID, observer_.availability());
+  EXPECT_TRUE(observer_.config().proxy_rules().empty());
+}
+
+TEST_F(ProxyConfigServiceAndroidWithInitialConfigTest, TestInitialConfig) {
+  // Make sure that the initial config is set.
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
+
+  // Override the initial configuration.
+  ClearConfiguration();
+  AddProperty("http.proxyHost", "httpproxy.com");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "PROXY httpproxy.com:80");
+}
+
+// !! The following test cases are automatically generated from
+// !! net/android/tools/proxy_test_cases.py.
+// !! Please edit that file instead of editing the test cases below and
+// !! update also the corresponding Java unit tests in
+// !! AndroidProxySelectorTest.java
+
+TEST_F(ProxyConfigServiceAndroidTest, NoProxy) {
+  // Test direct mapping when no proxy defined.
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("https://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostAndPort) {
+  // Test http.proxyHost and http.proxyPort works.
+  AddProperty("http.proxyHost", "httpproxy.com");
+  AddProperty("http.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
+  TestMapping("https://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostOnly) {
+  // We should get the default port (80) for proxied hosts.
+  AddProperty("http.proxyHost", "httpproxy.com");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "PROXY httpproxy.com:80");
+  TestMapping("https://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxyPortOnly) {
+  // http.proxyPort only should not result in any hosts being proxied.
+  AddProperty("http.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("https://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpNonProxyHosts1) {
+  // Test that HTTP non proxy hosts are mapped correctly
+  AddProperty("http.nonProxyHosts", "slashdot.org");
+  AddProperty("http.proxyHost", "httpproxy.com");
+  AddProperty("http.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
+  TestMapping("http://slashdot.org/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpNonProxyHosts2) {
+  // Test that | pattern works.
+  AddProperty("http.nonProxyHosts", "slashdot.org|freecode.net");
+  AddProperty("http.proxyHost", "httpproxy.com");
+  AddProperty("http.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "PROXY httpproxy.com:8080");
+  TestMapping("http://freecode.net/", "DIRECT");
+  TestMapping("http://slashdot.org/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpNonProxyHosts3) {
+  // Test that * pattern works.
+  AddProperty("http.nonProxyHosts", "*example.com");
+  AddProperty("http.proxyHost", "httpproxy.com");
+  AddProperty("http.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("http://slashdot.org/", "PROXY httpproxy.com:8080");
+  TestMapping("http://www.example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, FtpNonProxyHosts) {
+  // Test that FTP non proxy hosts are mapped correctly
+  AddProperty("ftp.nonProxyHosts", "slashdot.org");
+  AddProperty("ftp.proxyHost", "httpproxy.com");
+  AddProperty("ftp.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "PROXY httpproxy.com:8080");
+  TestMapping("http://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, FtpProxyHostAndPort) {
+  // Test ftp.proxyHost and ftp.proxyPort works.
+  AddProperty("ftp.proxyHost", "httpproxy.com");
+  AddProperty("ftp.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "PROXY httpproxy.com:8080");
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("https://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, FtpProxyHostOnly) {
+  // Test ftp.proxyHost and default port.
+  AddProperty("ftp.proxyHost", "httpproxy.com");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "PROXY httpproxy.com:80");
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("https://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpsProxyHostAndPort) {
+  // Test https.proxyHost and https.proxyPort works.
+  AddProperty("https.proxyHost", "httpproxy.com");
+  AddProperty("https.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("https://example.com/", "PROXY httpproxy.com:8080");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpsProxyHostOnly) {
+  // Test https.proxyHost and default port.
+  AddProperty("https.proxyHost", "httpproxy.com");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "DIRECT");
+  TestMapping("https://example.com/", "PROXY httpproxy.com:80");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostIPv6) {
+  // Test IPv6 https.proxyHost and default port.
+  AddProperty("http.proxyHost", "a:b:c::d:1");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "PROXY [a:b:c::d:1]:80");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostAndPortIPv6) {
+  // Test IPv6 http.proxyHost and http.proxyPort works.
+  AddProperty("http.proxyHost", "a:b:c::d:1");
+  AddProperty("http.proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "PROXY [a:b:c::d:1]:8080");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxyHostAndInvalidPort) {
+  // Test invalid http.proxyPort does not crash.
+  AddProperty("http.proxyHost", "a:b:c::d:1");
+  AddProperty("http.proxyPort", "65536");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "DIRECT");
+  TestMapping("http://example.com/", "DIRECT");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, DefaultProxyExplictPort) {
+  // Default http proxy is used if a scheme-specific one is not found.
+  AddProperty("ftp.proxyHost", "httpproxy.com");
+  AddProperty("ftp.proxyPort", "8080");
+  AddProperty("proxyHost", "defaultproxy.com");
+  AddProperty("proxyPort", "8080");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com/", "PROXY httpproxy.com:8080");
+  TestMapping("http://example.com/", "PROXY defaultproxy.com:8080");
+  TestMapping("https://example.com/", "PROXY defaultproxy.com:8080");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, DefaultProxyDefaultPort) {
+  // Check that the default proxy port is as expected.
+  AddProperty("proxyHost", "defaultproxy.com");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "PROXY defaultproxy.com:80");
+  TestMapping("https://example.com/", "PROXY defaultproxy.com:80");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, FallbackToSocks) {
+  // SOCKS proxy is used if scheme-specific one is not found.
+  AddProperty("http.proxyHost", "defaultproxy.com");
+  AddProperty("socksProxyHost", "socksproxy.com");
+  ProxySettingsChanged();
+  TestMapping("ftp://example.com", "SOCKS5 socksproxy.com:1080");
+  TestMapping("http://example.com/", "PROXY defaultproxy.com:80");
+  TestMapping("https://example.com/", "SOCKS5 socksproxy.com:1080");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, SocksExplicitPort) {
+  // SOCKS proxy port is used if specified
+  AddProperty("socksProxyHost", "socksproxy.com");
+  AddProperty("socksProxyPort", "9000");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "SOCKS5 socksproxy.com:9000");
+}
+
+TEST_F(ProxyConfigServiceAndroidTest, HttpProxySupercedesSocks) {
+  // SOCKS proxy is ignored if default HTTP proxy defined.
+  AddProperty("proxyHost", "defaultproxy.com");
+  AddProperty("socksProxyHost", "socksproxy.com");
+  AddProperty("socksProxyPort", "9000");
+  ProxySettingsChanged();
+  TestMapping("http://example.com/", "PROXY defaultproxy.com:80");
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_common_unittest.cc b/src/net/proxy/proxy_config_service_common_unittest.cc
new file mode 100644
index 0000000..429abc5
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_common_unittest.cc
@@ -0,0 +1,166 @@
+// Copyright (c) 2009 The Chromium Authors. 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/proxy/proxy_config_service_common_unittest.h"
+
+#include <string>
+#include <vector>
+
+#include "net/proxy/proxy_config.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// Helper to verify that |expected_proxy| matches |actual_proxy|. If it does
+// not, then |*did_fail| is set to true, and |*failure_details| is filled with
+// a description of the failure.
+void MatchesProxyServerHelper(const char* failure_message,
+                              const char* expected_proxy,
+                              const ProxyServer& actual_proxy,
+                              ::testing::AssertionResult* failure_details,
+                              bool* did_fail) {
+  std::string actual_proxy_string;
+  if (actual_proxy.is_valid())
+    actual_proxy_string = actual_proxy.ToURI();
+
+  if (std::string(expected_proxy) != actual_proxy_string) {
+    *failure_details
+        << failure_message << ". Was expecting: \"" << expected_proxy
+        << "\" but got: \"" << actual_proxy_string << "\"";
+    *did_fail = true;
+  }
+}
+
+std::string FlattenProxyBypass(const ProxyBypassRules& bypass_rules) {
+  std::string flattened_proxy_bypass;
+  for (ProxyBypassRules::RuleList::const_iterator it =
+       bypass_rules.rules().begin();
+       it != bypass_rules.rules().end(); ++it) {
+    if (!flattened_proxy_bypass.empty())
+      flattened_proxy_bypass += ",";
+    flattened_proxy_bypass += (*it)->ToString();
+  }
+  return flattened_proxy_bypass;
+}
+
+}  // namespace
+
+ProxyRulesExpectation::ProxyRulesExpectation(
+    ProxyConfig::ProxyRules::Type type,
+    const char* single_proxy,
+    const char* proxy_for_http,
+    const char* proxy_for_https,
+    const char* proxy_for_ftp,
+    const char* fallback_proxy,
+    const char* flattened_bypass_rules,
+    bool reverse_bypass)
+    : type(type),
+      single_proxy(single_proxy),
+      proxy_for_http(proxy_for_http),
+      proxy_for_https(proxy_for_https),
+      proxy_for_ftp(proxy_for_ftp),
+      fallback_proxy(fallback_proxy),
+      flattened_bypass_rules(flattened_bypass_rules),
+      reverse_bypass(reverse_bypass) {
+}
+
+
+::testing::AssertionResult ProxyRulesExpectation::Matches(
+    const ProxyConfig::ProxyRules& rules) const {
+  ::testing::AssertionResult failure_details = ::testing::AssertionFailure();
+  bool failed = false;
+
+  if (rules.type != type) {
+    failure_details << "Type mismatch. Expected: "
+                    << type << " but was: " << rules.type;
+    failed = true;
+  }
+
+  MatchesProxyServerHelper("Bad single_proxy", single_proxy,
+                           rules.single_proxy, &failure_details, &failed);
+  MatchesProxyServerHelper("Bad proxy_for_http", proxy_for_http,
+                           rules.proxy_for_http, &failure_details, &failed);
+  MatchesProxyServerHelper("Bad proxy_for_https", proxy_for_https,
+                           rules.proxy_for_https, &failure_details, &failed);
+  MatchesProxyServerHelper("Bad fallback_proxy", fallback_proxy,
+                           rules.fallback_proxy, &failure_details, &failed);
+
+  std::string actual_flattened_bypass = FlattenProxyBypass(rules.bypass_rules);
+  if (std::string(flattened_bypass_rules) != actual_flattened_bypass) {
+    failure_details
+        << "Bad bypass rules. Expected: \"" << flattened_bypass_rules
+        << "\" but got: \"" << actual_flattened_bypass << "\"";
+    failed = true;
+  }
+
+  if (rules.reverse_bypass != reverse_bypass) {
+    failure_details << "Bad reverse_bypass. Expected: " << reverse_bypass
+                    << " but got: " << rules.reverse_bypass;
+    failed = true;
+  }
+
+  return failed ? failure_details : ::testing::AssertionSuccess();
+}
+
+// static
+ProxyRulesExpectation ProxyRulesExpectation::Empty() {
+  return ProxyRulesExpectation(ProxyConfig::ProxyRules::TYPE_NO_RULES,
+                               "", "", "", "", "", "", false);
+}
+
+// static
+ProxyRulesExpectation ProxyRulesExpectation::EmptyWithBypass(
+    const char* flattened_bypass_rules) {
+  return ProxyRulesExpectation(ProxyConfig::ProxyRules::TYPE_NO_RULES,
+                               "", "", "", "", "", flattened_bypass_rules,
+                               false);
+}
+
+// static
+ProxyRulesExpectation ProxyRulesExpectation::Single(
+    const char* single_proxy,
+    const char* flattened_bypass_rules) {
+  return ProxyRulesExpectation(ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY,
+                               single_proxy, "", "", "", "",
+                               flattened_bypass_rules, false);
+}
+
+// static
+ProxyRulesExpectation ProxyRulesExpectation::PerScheme(
+    const char* proxy_http,
+    const char* proxy_https,
+    const char* proxy_ftp,
+    const char* flattened_bypass_rules) {
+  return ProxyRulesExpectation(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+                               "", proxy_http, proxy_https, proxy_ftp, "",
+                               flattened_bypass_rules, false);
+}
+
+// static
+ProxyRulesExpectation ProxyRulesExpectation::PerSchemeWithSocks(
+    const char* proxy_http,
+    const char* proxy_https,
+    const char* proxy_ftp,
+    const char* socks_proxy,
+    const char* flattened_bypass_rules) {
+  return ProxyRulesExpectation(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+                               "", proxy_http, proxy_https, proxy_ftp,
+                               socks_proxy, flattened_bypass_rules, false);
+}
+
+// static
+ProxyRulesExpectation ProxyRulesExpectation::PerSchemeWithBypassReversed(
+    const char* proxy_http,
+    const char* proxy_https,
+    const char* proxy_ftp,
+    const char* flattened_bypass_rules) {
+  return ProxyRulesExpectation(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+                               "", proxy_http, proxy_https, proxy_ftp, "",
+                               flattened_bypass_rules, true);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_common_unittest.h b/src/net/proxy/proxy_config_service_common_unittest.h
new file mode 100644
index 0000000..dbacbab
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_common_unittest.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2010 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_COMMON_UNITTEST_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_COMMON_UNITTEST_H_
+
+#include "net/proxy/proxy_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Helper functions to describe the expected value of a
+// ProxyConfig::ProxyRules, and to check for a match.
+
+namespace net {
+
+// This structure contains our expectations on what values the ProxyRules
+// should have.
+struct ProxyRulesExpectation {
+  ProxyRulesExpectation(ProxyConfig::ProxyRules::Type type,
+                        const char* single_proxy,
+                        const char* proxy_for_http,
+                        const char* proxy_for_https,
+                        const char* proxy_for_ftp,
+                        const char* fallback_proxy,
+                        const char* flattened_bypass_rules,
+                        bool reverse_bypass);
+
+  // Call this within an EXPECT_TRUE(), to assert that |rules| matches
+  // our expected values |*this|.
+  ::testing::AssertionResult Matches(
+      const ProxyConfig::ProxyRules& rules) const;
+
+  // Creates an expectation that the ProxyRules has no rules.
+  static ProxyRulesExpectation Empty();
+
+  // Creates an expectation that the ProxyRules has nothing other than
+  // the specified bypass rules.
+  static ProxyRulesExpectation EmptyWithBypass(
+      const char* flattened_bypass_rules);
+
+  // Creates an expectation that the ProxyRules is for a single proxy
+  // server for all schemes.
+  static ProxyRulesExpectation Single(const char* single_proxy,
+                                      const char* flattened_bypass_rules);
+
+  // Creates an expectation that the ProxyRules specifies a different
+  // proxy server for each URL scheme.
+  static ProxyRulesExpectation PerScheme(const char* proxy_http,
+                                         const char* proxy_https,
+                                         const char* proxy_ftp,
+                                         const char* flattened_bypass_rules);
+
+  // Same as above, but additionally with a SOCKS fallback.
+  static ProxyRulesExpectation PerSchemeWithSocks(
+      const char* proxy_http,
+      const char* proxy_https,
+      const char* proxy_ftp,
+      const char* fallback_proxy,
+      const char* flattened_bypass_rules);
+
+  // Same as PerScheme, but with the bypass rules reversed
+  static ProxyRulesExpectation PerSchemeWithBypassReversed(
+      const char* proxy_http,
+      const char* proxy_https,
+      const char* proxy_ftp,
+      const char* flattened_bypass_rules);
+
+  ProxyConfig::ProxyRules::Type type;
+  const char* single_proxy;
+  const char* proxy_for_http;
+  const char* proxy_for_https;
+  const char* proxy_for_ftp;
+  const char* fallback_proxy;
+  const char* flattened_bypass_rules;
+  bool reverse_bypass;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_COMMON_UNITTEST_H_
diff --git a/src/net/proxy/proxy_config_service_fixed.cc b/src/net/proxy/proxy_config_service_fixed.cc
new file mode 100644
index 0000000..3081ea5
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_fixed.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/proxy_config_service_fixed.h"
+
+namespace net {
+
+ProxyConfigServiceFixed::ProxyConfigServiceFixed(const ProxyConfig& pc)
+    : pc_(pc) {
+}
+
+ProxyConfigServiceFixed::~ProxyConfigServiceFixed() {}
+
+ProxyConfigService::ConfigAvailability
+    ProxyConfigServiceFixed::GetLatestProxyConfig(ProxyConfig* config) {
+  *config = pc_;
+  return CONFIG_VALID;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_fixed.h b/src/net/proxy/proxy_config_service_fixed.h
new file mode 100644
index 0000000..af68739
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_fixed.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_FIXED_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_FIXED_H_
+
+#include "base/compiler_specific.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+
+namespace net {
+
+// Implementation of ProxyConfigService that returns a fixed result.
+class NET_EXPORT ProxyConfigServiceFixed : public ProxyConfigService {
+ public:
+  explicit ProxyConfigServiceFixed(const ProxyConfig& pc);
+  virtual ~ProxyConfigServiceFixed();
+
+  // ProxyConfigService methods:
+  virtual void AddObserver(Observer* /*observer*/) OVERRIDE {}
+  virtual void RemoveObserver(Observer* /*observer*/) OVERRIDE {}
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) OVERRIDE;
+
+ private:
+  ProxyConfig pc_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_FIXED_H_
diff --git a/src/net/proxy/proxy_config_service_ios.cc b/src/net/proxy/proxy_config_service_ios.cc
new file mode 100644
index 0000000..fdeb1bb
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_ios.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/proxy_config_service_ios.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CFNetwork/CFProxySupport.h>
+
+#include "base/message_loop.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/sys_string_conversions.h"
+#include "net/proxy/proxy_config.h"
+
+namespace net {
+
+namespace {
+
+const int kPollIntervalSec = 10;
+
+// Utility function to pull out a boolean value from a dictionary and return it,
+// returning a default value if the key is not present.
+bool GetBoolFromDictionary(CFDictionaryRef dict,
+                           CFStringRef key,
+                           bool default_value) {
+  CFNumberRef number =
+      base::mac::GetValueFromDictionary<CFNumberRef>(dict, key);
+  if (!number)
+    return default_value;
+
+  int int_value;
+  if (CFNumberGetValue(number, kCFNumberIntType, &int_value))
+    return int_value;
+  else
+    return default_value;
+}
+
+void GetCurrentProxyConfig(ProxyConfig* config) {
+  base::mac::ScopedCFTypeRef<CFDictionaryRef> config_dict(
+      CFNetworkCopySystemProxySettings());
+  DCHECK(config_dict);
+
+  // Auto-detect is not supported.
+  // The kCFNetworkProxiesProxyAutoDiscoveryEnable key is not available on iOS.
+
+  // PAC file
+
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kCFNetworkProxiesProxyAutoConfigEnable,
+                            false)) {
+    CFStringRef pac_url_ref = base::mac::GetValueFromDictionary<CFStringRef>(
+        config_dict.get(), kCFNetworkProxiesProxyAutoConfigURLString);
+    if (pac_url_ref)
+      config->set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
+  }
+
+  // Proxies (for now http).
+
+  // The following keys are not available on iOS:
+  //   kCFNetworkProxiesFTPEnable
+  //   kCFNetworkProxiesFTPProxy
+  //   kCFNetworkProxiesFTPPort
+  //   kCFNetworkProxiesHTTPSEnable
+  //   kCFNetworkProxiesHTTPSProxy
+  //   kCFNetworkProxiesHTTPSPort
+  //   kCFNetworkProxiesSOCKSEnable
+  //   kCFNetworkProxiesSOCKSProxy
+  //   kCFNetworkProxiesSOCKSPort
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kCFNetworkProxiesHTTPEnable,
+                            false)) {
+    ProxyServer proxy_server =
+        ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
+                                    config_dict.get(),
+                                    kCFNetworkProxiesHTTPProxy,
+                                    kCFNetworkProxiesHTTPPort);
+    if (proxy_server.is_valid()) {
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+      config->proxy_rules().proxy_for_http = proxy_server;
+      // Desktop Safari applies the HTTP proxy to http:// URLs only, but
+      // Mobile Safari applies the HTTP proxy to https:// URLs as well.
+      config->proxy_rules().proxy_for_https = proxy_server;
+    }
+  }
+
+  // Proxy bypass list is not supported.
+  // The kCFNetworkProxiesExceptionsList key is not available on iOS.
+
+  // Proxy bypass boolean is not supported.
+  // The kCFNetworkProxiesExcludeSimpleHostnames key is not available on iOS.
+
+  // Source
+  config->set_source(PROXY_CONFIG_SOURCE_SYSTEM);
+}
+
+}  // namespace
+
+ProxyConfigServiceIOS::ProxyConfigServiceIOS()
+    : PollingProxyConfigService(base::TimeDelta::FromSeconds(kPollIntervalSec),
+                                GetCurrentProxyConfig) {
+}
+
+ProxyConfigServiceIOS::~ProxyConfigServiceIOS() {
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_ios.h b/src/net/proxy/proxy_config_service_ios.h
new file mode 100644
index 0000000..bf8f76b
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_ios.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_IOS_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_IOS_H_
+
+#include "net/proxy/polling_proxy_config_service.h"
+
+namespace net {
+
+class ProxyConfigServiceIOS : public PollingProxyConfigService {
+ public:
+  // Constructs a ProxyConfigService that watches the iOS system proxy settings.
+  explicit ProxyConfigServiceIOS();
+  virtual ~ProxyConfigServiceIOS();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceIOS);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_IOS_H_
diff --git a/src/net/proxy/proxy_config_service_linux.cc b/src/net/proxy/proxy_config_service_linux.cc
new file mode 100644
index 0000000..c604820
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_linux.cc
@@ -0,0 +1,1760 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_config_service_linux.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#if defined(USE_GCONF)
+#include <gconf/gconf-client.h>
+#endif  // defined(USE_GCONF)
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/inotify.h>
+#include <unistd.h>
+
+#include <map>
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/environment.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/nix/xdg_util.h"
+#include "base/single_thread_task_runner.h"
+#include "base/string_number_conversions.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/timer.h"
+#include "googleurl/src/url_canon.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_util.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_server.h"
+
+#if defined(USE_GIO)
+#include "library_loaders/libgio.h"
+#endif  // defined(USE_GIO)
+
+namespace net {
+
+namespace {
+
+// Given a proxy hostname from a setting, returns that hostname with
+// an appropriate proxy server scheme prefix.
+// scheme indicates the desired proxy scheme: usually http, with
+// socks 4 or 5 as special cases.
+// TODO(arindam): Remove URI string manipulation by using MapUrlSchemeToProxy.
+std::string FixupProxyHostScheme(ProxyServer::Scheme scheme,
+                                 std::string host) {
+  if (scheme == ProxyServer::SCHEME_SOCKS5 &&
+      StartsWithASCII(host, "socks4://", false)) {
+    // We default to socks 5, but if the user specifically set it to
+    // socks4://, then use that.
+    scheme = ProxyServer::SCHEME_SOCKS4;
+  }
+  // Strip the scheme if any.
+  std::string::size_type colon = host.find("://");
+  if (colon != std::string::npos)
+    host = host.substr(colon + 3);
+  // If a username and perhaps password are specified, give a warning.
+  std::string::size_type at_sign = host.find("@");
+  // Should this be supported?
+  if (at_sign != std::string::npos) {
+    // ProxyConfig does not support authentication parameters, but Chrome
+    // will prompt for the password later. Disregard the
+    // authentication parameters and continue with this hostname.
+    LOG(WARNING) << "Proxy authentication parameters ignored, see bug 16709";
+    host = host.substr(at_sign + 1);
+  }
+  // If this is a socks proxy, prepend a scheme so as to tell
+  // ProxyServer. This also allows ProxyServer to choose the right
+  // default port.
+  if (scheme == ProxyServer::SCHEME_SOCKS4)
+    host = "socks4://" + host;
+  else if (scheme == ProxyServer::SCHEME_SOCKS5)
+    host = "socks5://" + host;
+  // If there is a trailing slash, remove it so |host| will parse correctly
+  // even if it includes a port number (since the slash is not numeric).
+  if (host.length() && host[host.length() - 1] == '/')
+    host.resize(host.length() - 1);
+  return host;
+}
+
+}  // namespace
+
+ProxyConfigServiceLinux::Delegate::~Delegate() {
+}
+
+bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVarForScheme(
+    const char* variable, ProxyServer::Scheme scheme,
+    ProxyServer* result_server) {
+  std::string env_value;
+  if (env_var_getter_->GetVar(variable, &env_value)) {
+    if (!env_value.empty()) {
+      env_value = FixupProxyHostScheme(scheme, env_value);
+      ProxyServer proxy_server =
+          ProxyServer::FromURI(env_value, ProxyServer::SCHEME_HTTP);
+      if (proxy_server.is_valid() && !proxy_server.is_direct()) {
+        *result_server = proxy_server;
+        return true;
+      } else {
+        LOG(ERROR) << "Failed to parse environment variable " << variable;
+      }
+    }
+  }
+  return false;
+}
+
+bool ProxyConfigServiceLinux::Delegate::GetProxyFromEnvVar(
+    const char* variable, ProxyServer* result_server) {
+  return GetProxyFromEnvVarForScheme(variable, ProxyServer::SCHEME_HTTP,
+                                     result_server);
+}
+
+bool ProxyConfigServiceLinux::Delegate::GetConfigFromEnv(ProxyConfig* config) {
+  // Check for automatic configuration first, in
+  // "auto_proxy". Possibly only the "environment_proxy" firefox
+  // extension has ever used this, but it still sounds like a good
+  // idea.
+  std::string auto_proxy;
+  if (env_var_getter_->GetVar("auto_proxy", &auto_proxy)) {
+    if (auto_proxy.empty()) {
+      // Defined and empty => autodetect
+      config->set_auto_detect(true);
+    } else {
+      // specified autoconfig URL
+      config->set_pac_url(GURL(auto_proxy));
+    }
+    return true;
+  }
+  // "all_proxy" is a shortcut to avoid defining {http,https,ftp}_proxy.
+  ProxyServer proxy_server;
+  if (GetProxyFromEnvVar("all_proxy", &proxy_server)) {
+    config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+    config->proxy_rules().single_proxy = proxy_server;
+  } else {
+    bool have_http = GetProxyFromEnvVar("http_proxy", &proxy_server);
+    if (have_http)
+      config->proxy_rules().proxy_for_http = proxy_server;
+    // It would be tempting to let http_proxy apply for all protocols
+    // if https_proxy and ftp_proxy are not defined. Googling turns up
+    // several documents that mention only http_proxy. But then the
+    // user really might not want to proxy https. And it doesn't seem
+    // like other apps do this. So we will refrain.
+    bool have_https = GetProxyFromEnvVar("https_proxy", &proxy_server);
+    if (have_https)
+      config->proxy_rules().proxy_for_https = proxy_server;
+    bool have_ftp = GetProxyFromEnvVar("ftp_proxy", &proxy_server);
+    if (have_ftp)
+      config->proxy_rules().proxy_for_ftp = proxy_server;
+    if (have_http || have_https || have_ftp) {
+      // mustn't change type unless some rules are actually set.
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+    }
+  }
+  if (config->proxy_rules().empty()) {
+    // If the above were not defined, try for socks.
+    // For environment variables, we default to version 5, per the gnome
+    // documentation: http://library.gnome.org/devel/gnet/stable/gnet-socks.html
+    ProxyServer::Scheme scheme = ProxyServer::SCHEME_SOCKS5;
+    std::string env_version;
+    if (env_var_getter_->GetVar("SOCKS_VERSION", &env_version)
+        && env_version == "4")
+      scheme = ProxyServer::SCHEME_SOCKS4;
+    if (GetProxyFromEnvVarForScheme("SOCKS_SERVER", scheme, &proxy_server)) {
+      config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+      config->proxy_rules().single_proxy = proxy_server;
+    }
+  }
+  // Look for the proxy bypass list.
+  std::string no_proxy;
+  env_var_getter_->GetVar("no_proxy", &no_proxy);
+  if (config->proxy_rules().empty()) {
+    // Having only "no_proxy" set, presumably to "*", makes it
+    // explicit that env vars do specify a configuration: having no
+    // rules specified only means the user explicitly asks for direct
+    // connections.
+    return !no_proxy.empty();
+  }
+  // Note that this uses "suffix" matching. So a bypass of "google.com"
+  // is understood to mean a bypass of "*google.com".
+  config->proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching(
+      no_proxy);
+  return true;
+}
+
+namespace {
+
+const int kDebounceTimeoutMilliseconds = 250;
+
+#if defined(USE_GCONF)
+// This setting getter uses gconf, as used in GNOME 2 and some GNOME 3 desktops.
+class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter {
+ public:
+  SettingGetterImplGConf()
+      : client_(NULL), system_proxy_id_(0), system_http_proxy_id_(0),
+        notify_delegate_(NULL) {
+  }
+
+  virtual ~SettingGetterImplGConf() {
+    // client_ should have been released before now, from
+    // Delegate::OnDestroy(), while running on the UI thread. However
+    // on exiting the process, it may happen that Delegate::OnDestroy()
+    // task is left pending on the glib loop after the loop was quit,
+    // and pending tasks may then be deleted without being run.
+    if (client_) {
+      // gconf client was not cleaned up.
+      if (task_runner_->BelongsToCurrentThread()) {
+        // We are on the UI thread so we can clean it safely. This is
+        // the case at least for ui_tests running under Valgrind in
+        // bug 16076.
+        VLOG(1) << "~SettingGetterImplGConf: releasing gconf client";
+        ShutDown();
+      } else {
+        // This is very bad! We are deleting the setting getter but we're not on
+        // the UI thread. This is not supposed to happen: the setting getter is
+        // owned by the proxy config service's delegate, which is supposed to be
+        // destroyed on the UI thread only. We will get change notifications to
+        // a deleted object if we continue here, so fail now.
+        LOG(FATAL) << "~SettingGetterImplGConf: deleting on wrong thread!";
+      }
+    }
+    DCHECK(!client_);
+  }
+
+  virtual bool Init(base::SingleThreadTaskRunner* glib_thread_task_runner,
+                    MessageLoopForIO* file_loop) OVERRIDE {
+    DCHECK(glib_thread_task_runner->BelongsToCurrentThread());
+    DCHECK(!client_);
+    DCHECK(!task_runner_);
+    task_runner_ = glib_thread_task_runner;
+    client_ = gconf_client_get_default();
+    if (!client_) {
+      // It's not clear whether/when this can return NULL.
+      LOG(ERROR) << "Unable to create a gconf client";
+      task_runner_ = NULL;
+      return false;
+    }
+    GError* error = NULL;
+    bool added_system_proxy = false;
+    // We need to add the directories for which we'll be asking
+    // for notifications, and we might as well ask to preload them.
+    // These need to be removed again in ShutDown(); we are careful
+    // here to only leave client_ non-NULL if both have been added.
+    gconf_client_add_dir(client_, "/system/proxy",
+                         GCONF_CLIENT_PRELOAD_ONELEVEL, &error);
+    if (error == NULL) {
+      added_system_proxy = true;
+      gconf_client_add_dir(client_, "/system/http_proxy",
+                           GCONF_CLIENT_PRELOAD_ONELEVEL, &error);
+    }
+    if (error != NULL) {
+      LOG(ERROR) << "Error requesting gconf directory: " << error->message;
+      g_error_free(error);
+      if (added_system_proxy)
+        gconf_client_remove_dir(client_, "/system/proxy", NULL);
+      g_object_unref(client_);
+      client_ = NULL;
+      task_runner_ = NULL;
+      return false;
+    }
+    return true;
+  }
+
+  virtual void ShutDown() OVERRIDE {
+    if (client_) {
+      DCHECK(task_runner_->BelongsToCurrentThread());
+      // We must explicitly disable gconf notifications here, because the gconf
+      // client will be shared between all setting getters, and they do not all
+      // have the same lifetimes. (For instance, incognito sessions get their
+      // own, which is destroyed when the session ends.)
+      gconf_client_notify_remove(client_, system_http_proxy_id_);
+      gconf_client_notify_remove(client_, system_proxy_id_);
+      gconf_client_remove_dir(client_, "/system/http_proxy", NULL);
+      gconf_client_remove_dir(client_, "/system/proxy", NULL);
+      g_object_unref(client_);
+      client_ = NULL;
+      task_runner_ = NULL;
+    }
+  }
+
+  virtual bool SetUpNotifications(
+      ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE {
+    DCHECK(client_);
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    GError* error = NULL;
+    notify_delegate_ = delegate;
+    // We have to keep track of the IDs returned by gconf_client_notify_add() so
+    // that we can remove them in ShutDown(). (Otherwise, notifications will be
+    // delivered to this object after it is deleted, which is bad, m'kay?)
+    system_proxy_id_ = gconf_client_notify_add(
+        client_, "/system/proxy",
+        OnGConfChangeNotification, this,
+        NULL, &error);
+    if (error == NULL) {
+      system_http_proxy_id_ = gconf_client_notify_add(
+          client_, "/system/http_proxy",
+          OnGConfChangeNotification, this,
+          NULL, &error);
+    }
+    if (error != NULL) {
+      LOG(ERROR) << "Error requesting gconf notifications: " << error->message;
+      g_error_free(error);
+      ShutDown();
+      return false;
+    }
+    // Simulate a change to avoid possibly losing updates before this point.
+    OnChangeNotification();
+    return true;
+  }
+
+  virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE {
+    return task_runner_;
+  }
+
+  virtual ProxyConfigSource GetConfigSource() OVERRIDE {
+    return PROXY_CONFIG_SOURCE_GCONF;
+  }
+
+  virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
+    switch (key) {
+      case PROXY_MODE:
+        return GetStringByPath("/system/proxy/mode", result);
+      case PROXY_AUTOCONF_URL:
+        return GetStringByPath("/system/proxy/autoconfig_url", result);
+      case PROXY_HTTP_HOST:
+        return GetStringByPath("/system/http_proxy/host", result);
+      case PROXY_HTTPS_HOST:
+        return GetStringByPath("/system/proxy/secure_host", result);
+      case PROXY_FTP_HOST:
+        return GetStringByPath("/system/proxy/ftp_host", result);
+      case PROXY_SOCKS_HOST:
+        return GetStringByPath("/system/proxy/socks_host", result);
+    }
+    return false;  // Placate compiler.
+  }
+  virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE {
+    switch (key) {
+      case PROXY_USE_HTTP_PROXY:
+        return GetBoolByPath("/system/http_proxy/use_http_proxy", result);
+      case PROXY_USE_SAME_PROXY:
+        return GetBoolByPath("/system/http_proxy/use_same_proxy", result);
+      case PROXY_USE_AUTHENTICATION:
+        return GetBoolByPath("/system/http_proxy/use_authentication", result);
+    }
+    return false;  // Placate compiler.
+  }
+  virtual bool GetInt(IntSetting key, int* result) OVERRIDE {
+    switch (key) {
+      case PROXY_HTTP_PORT:
+        return GetIntByPath("/system/http_proxy/port", result);
+      case PROXY_HTTPS_PORT:
+        return GetIntByPath("/system/proxy/secure_port", result);
+      case PROXY_FTP_PORT:
+        return GetIntByPath("/system/proxy/ftp_port", result);
+      case PROXY_SOCKS_PORT:
+        return GetIntByPath("/system/proxy/socks_port", result);
+    }
+    return false;  // Placate compiler.
+  }
+  virtual bool GetStringList(StringListSetting key,
+                             std::vector<std::string>* result) OVERRIDE {
+    switch (key) {
+      case PROXY_IGNORE_HOSTS:
+        return GetStringListByPath("/system/http_proxy/ignore_hosts", result);
+    }
+    return false;  // Placate compiler.
+  }
+
+  virtual bool BypassListIsReversed() OVERRIDE {
+    // This is a KDE-specific setting.
+    return false;
+  }
+
+  virtual bool MatchHostsUsingSuffixMatching() OVERRIDE {
+    return false;
+  }
+
+ private:
+  bool GetStringByPath(const char* key, std::string* result) {
+    DCHECK(client_);
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    GError* error = NULL;
+    gchar* value = gconf_client_get_string(client_, key, &error);
+    if (HandleGError(error, key))
+      return false;
+    if (!value)
+      return false;
+    *result = value;
+    g_free(value);
+    return true;
+  }
+  bool GetBoolByPath(const char* key, bool* result) {
+    DCHECK(client_);
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    GError* error = NULL;
+    // We want to distinguish unset values from values defaulting to
+    // false. For that we need to use the type-generic
+    // gconf_client_get() rather than gconf_client_get_bool().
+    GConfValue* gconf_value = gconf_client_get(client_, key, &error);
+    if (HandleGError(error, key))
+      return false;
+    if (!gconf_value) {
+      // Unset.
+      return false;
+    }
+    if (gconf_value->type != GCONF_VALUE_BOOL) {
+      gconf_value_free(gconf_value);
+      return false;
+    }
+    gboolean bool_value = gconf_value_get_bool(gconf_value);
+    *result = static_cast<bool>(bool_value);
+    gconf_value_free(gconf_value);
+    return true;
+  }
+  bool GetIntByPath(const char* key, int* result) {
+    DCHECK(client_);
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    GError* error = NULL;
+    int value = gconf_client_get_int(client_, key, &error);
+    if (HandleGError(error, key))
+      return false;
+    // We don't bother to distinguish an unset value because callers
+    // don't care. 0 is returned if unset.
+    *result = value;
+    return true;
+  }
+  bool GetStringListByPath(const char* key, std::vector<std::string>* result) {
+    DCHECK(client_);
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    GError* error = NULL;
+    GSList* list = gconf_client_get_list(client_, key,
+                                         GCONF_VALUE_STRING, &error);
+    if (HandleGError(error, key))
+      return false;
+    if (!list)
+      return false;
+    for (GSList *it = list; it; it = it->next) {
+      result->push_back(static_cast<char*>(it->data));
+      g_free(it->data);
+    }
+    g_slist_free(list);
+    return true;
+  }
+
+  // Logs and frees a glib error. Returns false if there was no error
+  // (error is NULL).
+  bool HandleGError(GError* error, const char* key) {
+    if (error != NULL) {
+      LOG(ERROR) << "Error getting gconf value for " << key
+                 << ": " << error->message;
+      g_error_free(error);
+      return true;
+    }
+    return false;
+  }
+
+  // This is the callback from the debounce timer.
+  void OnDebouncedNotification() {
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    CHECK(notify_delegate_);
+    // Forward to a method on the proxy config service delegate object.
+    notify_delegate_->OnCheckProxyConfigSettings();
+  }
+
+  void OnChangeNotification() {
+    // We don't use Reset() because the timer may not yet be running.
+    // (In that case Stop() is a no-op.)
+    debounce_timer_.Stop();
+    debounce_timer_.Start(FROM_HERE,
+        base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds),
+        this, &SettingGetterImplGConf::OnDebouncedNotification);
+  }
+
+  // gconf notification callback, dispatched on the default glib main loop.
+  static void OnGConfChangeNotification(GConfClient* client, guint cnxn_id,
+                                        GConfEntry* entry, gpointer user_data) {
+    VLOG(1) << "gconf change notification for key "
+            << gconf_entry_get_key(entry);
+    // We don't track which key has changed, just that something did change.
+    SettingGetterImplGConf* setting_getter =
+        reinterpret_cast<SettingGetterImplGConf*>(user_data);
+    setting_getter->OnChangeNotification();
+  }
+
+  GConfClient* client_;
+  // These ids are the values returned from gconf_client_notify_add(), which we
+  // will need in order to later call gconf_client_notify_remove().
+  guint system_proxy_id_;
+  guint system_http_proxy_id_;
+
+  ProxyConfigServiceLinux::Delegate* notify_delegate_;
+  base::OneShotTimer<SettingGetterImplGConf> debounce_timer_;
+
+  // Task runner for the thread that we make gconf calls on. It should
+  // be the UI thread and all our methods should be called on this
+  // thread. Only for assertions.
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf);
+};
+#endif  // defined(USE_GCONF)
+
+#if defined(USE_GIO)
+// This setting getter uses gsettings, as used in most GNOME 3 desktops.
+class SettingGetterImplGSettings
+    : public ProxyConfigServiceLinux::SettingGetter {
+ public:
+  SettingGetterImplGSettings() :
+    client_(NULL),
+    http_client_(NULL),
+    https_client_(NULL),
+    ftp_client_(NULL),
+    socks_client_(NULL),
+    notify_delegate_(NULL) {
+  }
+
+  virtual ~SettingGetterImplGSettings() {
+    // client_ should have been released before now, from
+    // Delegate::OnDestroy(), while running on the UI thread. However
+    // on exiting the process, it may happen that
+    // Delegate::OnDestroy() task is left pending on the glib loop
+    // after the loop was quit, and pending tasks may then be deleted
+    // without being run.
+    if (client_) {
+      // gconf client was not cleaned up.
+      if (task_runner_->BelongsToCurrentThread()) {
+        // We are on the UI thread so we can clean it safely. This is
+        // the case at least for ui_tests running under Valgrind in
+        // bug 16076.
+        VLOG(1) << "~SettingGetterImplGSettings: releasing gsettings client";
+        ShutDown();
+      } else {
+        LOG(WARNING) << "~SettingGetterImplGSettings: leaking gsettings client";
+        client_ = NULL;
+      }
+    }
+    DCHECK(!client_);
+  }
+
+  bool SchemaExists(const char* schema_name) {
+    const gchar* const* schemas = libgio_loader_.g_settings_list_schemas();
+    while (*schemas) {
+      if (strcmp(schema_name, static_cast<const char*>(*schemas)) == 0)
+        return true;
+      schemas++;
+    }
+    return false;
+  }
+
+  // LoadAndCheckVersion() must be called *before* Init()!
+  bool LoadAndCheckVersion(base::Environment* env);
+
+  virtual bool Init(base::SingleThreadTaskRunner* glib_thread_task_runner,
+                    MessageLoopForIO* file_loop) OVERRIDE {
+    DCHECK(glib_thread_task_runner->BelongsToCurrentThread());
+    DCHECK(!client_);
+    DCHECK(!task_runner_);
+
+    if (!SchemaExists("org.gnome.system.proxy") ||
+        !(client_ = libgio_loader_.g_settings_new("org.gnome.system.proxy"))) {
+      // It's not clear whether/when this can return NULL.
+      LOG(ERROR) << "Unable to create a gsettings client";
+      return false;
+    }
+    task_runner_ = glib_thread_task_runner;
+    // We assume these all work if the above call worked.
+    http_client_ = libgio_loader_.g_settings_get_child(client_, "http");
+    https_client_ = libgio_loader_.g_settings_get_child(client_, "https");
+    ftp_client_ = libgio_loader_.g_settings_get_child(client_, "ftp");
+    socks_client_ = libgio_loader_.g_settings_get_child(client_, "socks");
+    DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_);
+    return true;
+  }
+
+  virtual void ShutDown() OVERRIDE {
+    if (client_) {
+      DCHECK(task_runner_->BelongsToCurrentThread());
+      // This also disables gsettings notifications.
+      g_object_unref(socks_client_);
+      g_object_unref(ftp_client_);
+      g_object_unref(https_client_);
+      g_object_unref(http_client_);
+      g_object_unref(client_);
+      // We only need to null client_ because it's the only one that we check.
+      client_ = NULL;
+      task_runner_ = NULL;
+    }
+  }
+
+  virtual bool SetUpNotifications(
+      ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE {
+    DCHECK(client_);
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    notify_delegate_ = delegate;
+    // We could watch for the change-event signal instead of changed, but
+    // since we have to watch more than one object, we'd still have to
+    // debounce change notifications. This is conceptually simpler.
+    g_signal_connect(G_OBJECT(client_), "changed",
+                     G_CALLBACK(OnGSettingsChangeNotification), this);
+    g_signal_connect(G_OBJECT(http_client_), "changed",
+                     G_CALLBACK(OnGSettingsChangeNotification), this);
+    g_signal_connect(G_OBJECT(https_client_), "changed",
+                     G_CALLBACK(OnGSettingsChangeNotification), this);
+    g_signal_connect(G_OBJECT(ftp_client_), "changed",
+                     G_CALLBACK(OnGSettingsChangeNotification), this);
+    g_signal_connect(G_OBJECT(socks_client_), "changed",
+                     G_CALLBACK(OnGSettingsChangeNotification), this);
+    // Simulate a change to avoid possibly losing updates before this point.
+    OnChangeNotification();
+    return true;
+  }
+
+  virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE {
+    return task_runner_;
+  }
+
+  virtual ProxyConfigSource GetConfigSource() OVERRIDE {
+    return PROXY_CONFIG_SOURCE_GSETTINGS;
+  }
+
+  virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
+    DCHECK(client_);
+    switch (key) {
+      case PROXY_MODE:
+        return GetStringByPath(client_, "mode", result);
+      case PROXY_AUTOCONF_URL:
+        return GetStringByPath(client_, "autoconfig-url", result);
+      case PROXY_HTTP_HOST:
+        return GetStringByPath(http_client_, "host", result);
+      case PROXY_HTTPS_HOST:
+        return GetStringByPath(https_client_, "host", result);
+      case PROXY_FTP_HOST:
+        return GetStringByPath(ftp_client_, "host", result);
+      case PROXY_SOCKS_HOST:
+        return GetStringByPath(socks_client_, "host", result);
+    }
+    return false;  // Placate compiler.
+  }
+  virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE {
+    DCHECK(client_);
+    switch (key) {
+      case PROXY_USE_HTTP_PROXY:
+        // Although there is an "enabled" boolean in http_client_, it is not set
+        // to true by the proxy config utility. We ignore it and return false.
+        return false;
+      case PROXY_USE_SAME_PROXY:
+        // Similarly, although there is a "use-same-proxy" boolean in client_,
+        // it is never set to false by the proxy config utility. We ignore it.
+        return false;
+      case PROXY_USE_AUTHENTICATION:
+        // There is also no way to set this in the proxy config utility, but it
+        // doesn't hurt us to get the actual setting (unlike the two above).
+        return GetBoolByPath(http_client_, "use-authentication", result);
+    }
+    return false;  // Placate compiler.
+  }
+  virtual bool GetInt(IntSetting key, int* result) OVERRIDE {
+    DCHECK(client_);
+    switch (key) {
+      case PROXY_HTTP_PORT:
+        return GetIntByPath(http_client_, "port", result);
+      case PROXY_HTTPS_PORT:
+        return GetIntByPath(https_client_, "port", result);
+      case PROXY_FTP_PORT:
+        return GetIntByPath(ftp_client_, "port", result);
+      case PROXY_SOCKS_PORT:
+        return GetIntByPath(socks_client_, "port", result);
+    }
+    return false;  // Placate compiler.
+  }
+  virtual bool GetStringList(StringListSetting key,
+                             std::vector<std::string>* result) OVERRIDE {
+    DCHECK(client_);
+    switch (key) {
+      case PROXY_IGNORE_HOSTS:
+        return GetStringListByPath(client_, "ignore-hosts", result);
+    }
+    return false;  // Placate compiler.
+  }
+
+  virtual bool BypassListIsReversed() OVERRIDE {
+    // This is a KDE-specific setting.
+    return false;
+  }
+
+  virtual bool MatchHostsUsingSuffixMatching() OVERRIDE {
+    return false;
+  }
+
+ private:
+  bool GetStringByPath(GSettings* client, const char* key,
+                       std::string* result) {
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    gchar* value = libgio_loader_.g_settings_get_string(client, key);
+    if (!value)
+      return false;
+    *result = value;
+    g_free(value);
+    return true;
+  }
+  bool GetBoolByPath(GSettings* client, const char* key, bool* result) {
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    *result = static_cast<bool>(
+        libgio_loader_.g_settings_get_boolean(client, key));
+    return true;
+  }
+  bool GetIntByPath(GSettings* client, const char* key, int* result) {
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    *result = libgio_loader_.g_settings_get_int(client, key);
+    return true;
+  }
+  bool GetStringListByPath(GSettings* client, const char* key,
+                           std::vector<std::string>* result) {
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    gchar** list = libgio_loader_.g_settings_get_strv(client, key);
+    if (!list)
+      return false;
+    for (size_t i = 0; list[i]; ++i) {
+      result->push_back(static_cast<char*>(list[i]));
+      g_free(list[i]);
+    }
+    g_free(list);
+    return true;
+  }
+
+  // This is the callback from the debounce timer.
+  void OnDebouncedNotification() {
+    DCHECK(task_runner_->BelongsToCurrentThread());
+    CHECK(notify_delegate_);
+    // Forward to a method on the proxy config service delegate object.
+    notify_delegate_->OnCheckProxyConfigSettings();
+  }
+
+  void OnChangeNotification() {
+    // We don't use Reset() because the timer may not yet be running.
+    // (In that case Stop() is a no-op.)
+    debounce_timer_.Stop();
+    debounce_timer_.Start(FROM_HERE,
+        base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds),
+        this, &SettingGetterImplGSettings::OnDebouncedNotification);
+  }
+
+  // gsettings notification callback, dispatched on the default glib main loop.
+  static void OnGSettingsChangeNotification(GSettings* client, gchar* key,
+                                            gpointer user_data) {
+    VLOG(1) << "gsettings change notification for key " << key;
+    // We don't track which key has changed, just that something did change.
+    SettingGetterImplGSettings* setting_getter =
+        reinterpret_cast<SettingGetterImplGSettings*>(user_data);
+    setting_getter->OnChangeNotification();
+  }
+
+  GSettings* client_;
+  GSettings* http_client_;
+  GSettings* https_client_;
+  GSettings* ftp_client_;
+  GSettings* socks_client_;
+  ProxyConfigServiceLinux::Delegate* notify_delegate_;
+  base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_;
+
+  // Task runner for the thread that we make gsettings calls on. It should
+  // be the UI thread and all our methods should be called on this
+  // thread. Only for assertions.
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+  LibGioLoader libgio_loader_;
+
+  DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings);
+};
+
+bool SettingGetterImplGSettings::LoadAndCheckVersion(
+    base::Environment* env) {
+  // LoadAndCheckVersion() must be called *before* Init()!
+  DCHECK(!client_);
+
+  // The APIs to query gsettings were introduced after the minimum glib
+  // version we target, so we can't link directly against them. We load them
+  // dynamically at runtime, and if they don't exist, return false here. (We
+  // support linking directly via gyp flags though.) Additionally, even when
+  // they are present, we do two additional checks to make sure we should use
+  // them and not gconf. First, we attempt to load the schema for proxy
+  // settings. Second, we check for the program that was used in older
+  // versions of GNOME to configure proxy settings, and return false if it
+  // exists. Some distributions (e.g. Ubuntu 11.04) have the API and schema
+  // but don't use gsettings for proxy settings, but they do have the old
+  // binary, so we detect these systems that way.
+
+  {
+    // TODO(phajdan.jr): Redesign the code to load library on different thread.
+    base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+    // Try also without .0 at the end; on some systems this may be required.
+    if (!libgio_loader_.Load("libgio-2.0.so.0") &&
+        !libgio_loader_.Load("libgio-2.0.so")) {
+      VLOG(1) << "Cannot load gio library. Will fall back to gconf.";
+      return false;
+    }
+  }
+
+  GSettings* client;
+  if (!SchemaExists("org.gnome.system.proxy") ||
+      !(client = libgio_loader_.g_settings_new("org.gnome.system.proxy"))) {
+    VLOG(1) << "Cannot create gsettings client. Will fall back to gconf.";
+    return false;
+  }
+  g_object_unref(client);
+
+  std::string path;
+  if (!env->GetVar("PATH", &path)) {
+    LOG(ERROR) << "No $PATH variable. Assuming no gnome-network-properties.";
+  } else {
+    // Yes, we're on the UI thread. Yes, we're accessing the file system.
+    // Sadly, we don't have much choice. We need the proxy settings and we
+    // need them now, and to figure out where to get them, we have to check
+    // for this binary. See http://crbug.com/69057 for additional details.
+    base::ThreadRestrictions::ScopedAllowIO allow_io;
+    std::vector<std::string> paths;
+    Tokenize(path, ":", &paths);
+    for (size_t i = 0; i < paths.size(); ++i) {
+      FilePath file(paths[i]);
+      if (file_util::PathExists(file.Append("gnome-network-properties"))) {
+        VLOG(1) << "Found gnome-network-properties. Will fall back to gconf.";
+        return false;
+      }
+    }
+  }
+
+  VLOG(1) << "All gsettings tests OK. Will get proxy config from gsettings.";
+  return true;
+}
+#endif  // defined(USE_GIO)
+
+// This is the KDE version that reads kioslaverc and simulates gconf.
+// Doing this allows the main Delegate code, as well as the unit tests
+// for it, to stay the same - and the settings map fairly well besides.
+class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter,
+                             public base::MessagePumpLibevent::Watcher {
+ public:
+  explicit SettingGetterImplKDE(base::Environment* env_var_getter)
+      : inotify_fd_(-1), notify_delegate_(NULL), indirect_manual_(false),
+        auto_no_pac_(false), reversed_bypass_list_(false),
+        env_var_getter_(env_var_getter), file_loop_(NULL) {
+    // This has to be called on the UI thread (http://crbug.com/69057).
+    base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+    // Derive the location of the kde config dir from the environment.
+    std::string home;
+    if (env_var_getter->GetVar("KDEHOME", &home) && !home.empty()) {
+      // $KDEHOME is set. Use it unconditionally.
+      kde_config_dir_ = KDEHomeToConfigPath(FilePath(home));
+    } else {
+      // $KDEHOME is unset. Try to figure out what to use. This seems to be
+      // the common case on most distributions.
+      if (!env_var_getter->GetVar(base::env_vars::kHome, &home))
+        // User has no $HOME? Give up. Later we'll report the failure.
+        return;
+      if (base::nix::GetDesktopEnvironment(env_var_getter) ==
+          base::nix::DESKTOP_ENVIRONMENT_KDE3) {
+        // KDE3 always uses .kde for its configuration.
+        FilePath kde_path = FilePath(home).Append(".kde");
+        kde_config_dir_ = KDEHomeToConfigPath(kde_path);
+      } else {
+        // Some distributions patch KDE4 to use .kde4 instead of .kde, so that
+        // both can be installed side-by-side. Sadly they don't all do this, and
+        // they don't always do this: some distributions have started switching
+        // back as well. So if there is a .kde4 directory, check the timestamps
+        // of the config directories within and use the newest one.
+        // Note that we should currently be running in the UI thread, because in
+        // the gconf version, that is the only thread that can access the proxy
+        // settings (a gconf restriction). As noted below, the initial read of
+        // the proxy settings will be done in this thread anyway, so we check
+        // for .kde4 here in this thread as well.
+        FilePath kde3_path = FilePath(home).Append(".kde");
+        FilePath kde3_config = KDEHomeToConfigPath(kde3_path);
+        FilePath kde4_path = FilePath(home).Append(".kde4");
+        FilePath kde4_config = KDEHomeToConfigPath(kde4_path);
+        bool use_kde4 = false;
+        if (file_util::DirectoryExists(kde4_path)) {
+          base::PlatformFileInfo kde3_info;
+          base::PlatformFileInfo kde4_info;
+          if (file_util::GetFileInfo(kde4_config, &kde4_info)) {
+            if (file_util::GetFileInfo(kde3_config, &kde3_info)) {
+              use_kde4 = kde4_info.last_modified >= kde3_info.last_modified;
+            } else {
+              use_kde4 = true;
+            }
+          }
+        }
+        if (use_kde4) {
+          kde_config_dir_ = KDEHomeToConfigPath(kde4_path);
+        } else {
+          kde_config_dir_ = KDEHomeToConfigPath(kde3_path);
+        }
+      }
+    }
+  }
+
+  virtual ~SettingGetterImplKDE() {
+    // inotify_fd_ should have been closed before now, from
+    // Delegate::OnDestroy(), while running on the file thread. However
+    // on exiting the process, it may happen that Delegate::OnDestroy()
+    // task is left pending on the file loop after the loop was quit,
+    // and pending tasks may then be deleted without being run.
+    // Here in the KDE version, we can safely close the file descriptor
+    // anyway. (Not that it really matters; the process is exiting.)
+    if (inotify_fd_ >= 0)
+      ShutDown();
+    DCHECK(inotify_fd_ < 0);
+  }
+
+  virtual bool Init(base::SingleThreadTaskRunner* glib_thread_task_runner,
+                    MessageLoopForIO* file_loop) OVERRIDE {
+    // This has to be called on the UI thread (http://crbug.com/69057).
+    base::ThreadRestrictions::ScopedAllowIO allow_io;
+    DCHECK(inotify_fd_ < 0);
+    inotify_fd_ = inotify_init();
+    if (inotify_fd_ < 0) {
+      PLOG(ERROR) << "inotify_init failed";
+      return false;
+    }
+    int flags = fcntl(inotify_fd_, F_GETFL);
+    if (fcntl(inotify_fd_, F_SETFL, flags | O_NONBLOCK) < 0) {
+      PLOG(ERROR) << "fcntl failed";
+      close(inotify_fd_);
+      inotify_fd_ = -1;
+      return false;
+    }
+    file_loop_ = file_loop;
+    // The initial read is done on the current thread, not |file_loop_|,
+    // since we will need to have it for SetUpAndFetchInitialConfig().
+    UpdateCachedSettings();
+    return true;
+  }
+
+  virtual void ShutDown() OVERRIDE {
+    if (inotify_fd_ >= 0) {
+      ResetCachedSettings();
+      inotify_watcher_.StopWatchingFileDescriptor();
+      close(inotify_fd_);
+      inotify_fd_ = -1;
+    }
+  }
+
+  virtual bool SetUpNotifications(
+      ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE {
+    DCHECK(inotify_fd_ >= 0);
+    DCHECK(MessageLoop::current() == file_loop_);
+    // We can't just watch the kioslaverc file directly, since KDE will write
+    // a new copy of it and then rename it whenever settings are changed and
+    // inotify watches inodes (so we'll be watching the old deleted file after
+    // the first change, and it will never change again). So, we watch the
+    // directory instead. We then act only on changes to the kioslaverc entry.
+    if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(),
+                          IN_MODIFY | IN_MOVED_TO) < 0)
+      return false;
+    notify_delegate_ = delegate;
+    if (!file_loop_->WatchFileDescriptor(inotify_fd_, true,
+            MessageLoopForIO::WATCH_READ, &inotify_watcher_, this))
+      return false;
+    // Simulate a change to avoid possibly losing updates before this point.
+    OnChangeNotification();
+    return true;
+  }
+
+  virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE {
+    return file_loop_ ? file_loop_->message_loop_proxy() : NULL;
+  }
+
+  // Implement base::MessagePumpLibevent::Watcher.
+  virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
+    DCHECK_EQ(fd, inotify_fd_);
+    DCHECK(MessageLoop::current() == file_loop_);
+    OnChangeNotification();
+  }
+  virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual ProxyConfigSource GetConfigSource() OVERRIDE {
+    return PROXY_CONFIG_SOURCE_KDE;
+  }
+
+  virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
+    string_map_type::iterator it = string_table_.find(key);
+    if (it == string_table_.end())
+      return false;
+    *result = it->second;
+    return true;
+  }
+  virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE {
+    // We don't ever have any booleans.
+    return false;
+  }
+  virtual bool GetInt(IntSetting key, int* result) OVERRIDE {
+    // We don't ever have any integers. (See AddProxy() below about ports.)
+    return false;
+  }
+  virtual bool GetStringList(StringListSetting key,
+                             std::vector<std::string>* result) OVERRIDE {
+    strings_map_type::iterator it = strings_table_.find(key);
+    if (it == strings_table_.end())
+      return false;
+    *result = it->second;
+    return true;
+  }
+
+  virtual bool BypassListIsReversed() OVERRIDE {
+    return reversed_bypass_list_;
+  }
+
+  virtual bool MatchHostsUsingSuffixMatching() OVERRIDE {
+    return true;
+  }
+
+ private:
+  void ResetCachedSettings() {
+    string_table_.clear();
+    strings_table_.clear();
+    indirect_manual_ = false;
+    auto_no_pac_ = false;
+    reversed_bypass_list_ = false;
+  }
+
+  FilePath KDEHomeToConfigPath(const FilePath& kde_home) {
+    return kde_home.Append("share").Append("config");
+  }
+
+  void AddProxy(StringSetting host_key, const std::string& value) {
+    if (value.empty() || value.substr(0, 3) == "//:")
+      // No proxy.
+      return;
+    size_t space = value.find(' ');
+    if (space != std::string::npos) {
+      // Newer versions of KDE use a space rather than a colon to separate the
+      // port number from the hostname. If we find this, we need to convert it.
+      std::string fixed = value;
+      fixed[space] = ':';
+      string_table_[host_key] = fixed;
+    } else {
+      // We don't need to parse the port number out; GetProxyFromSettings()
+      // would only append it right back again. So we just leave the port
+      // number right in the host string.
+      string_table_[host_key] = value;
+    }
+  }
+
+  void AddHostList(StringListSetting key, const std::string& value) {
+    std::vector<std::string> tokens;
+    StringTokenizer tk(value, ", ");
+    while (tk.GetNext()) {
+      std::string token = tk.token();
+      if (!token.empty())
+        tokens.push_back(token);
+    }
+    strings_table_[key] = tokens;
+  }
+
+  void AddKDESetting(const std::string& key, const std::string& value) {
+    if (key == "ProxyType") {
+      const char* mode = "none";
+      indirect_manual_ = false;
+      auto_no_pac_ = false;
+      int int_value;
+      base::StringToInt(value, &int_value);
+      switch (int_value) {
+        case 0:  // No proxy, or maybe kioslaverc syntax error.
+          break;
+        case 1:  // Manual configuration.
+          mode = "manual";
+          break;
+        case 2:  // PAC URL.
+          mode = "auto";
+          break;
+        case 3:  // WPAD.
+          mode = "auto";
+          auto_no_pac_ = true;
+          break;
+        case 4:  // Indirect manual via environment variables.
+          mode = "manual";
+          indirect_manual_ = true;
+          break;
+      }
+      string_table_[PROXY_MODE] = mode;
+    } else if (key == "Proxy Config Script") {
+      string_table_[PROXY_AUTOCONF_URL] = value;
+    } else if (key == "httpProxy") {
+      AddProxy(PROXY_HTTP_HOST, value);
+    } else if (key == "httpsProxy") {
+      AddProxy(PROXY_HTTPS_HOST, value);
+    } else if (key == "ftpProxy") {
+      AddProxy(PROXY_FTP_HOST, value);
+    } else if (key == "socksProxy") {
+      // Older versions of KDE configure SOCKS in a weird way involving
+      // LD_PRELOAD and a library that intercepts network calls to SOCKSify
+      // them. We don't support it. KDE 4.8 added a proper SOCKS setting.
+      AddProxy(PROXY_SOCKS_HOST, value);
+    } else if (key == "ReversedException") {
+      // We count "true" or any nonzero number as true, otherwise false.
+      // Note that if the value is not actually numeric StringToInt()
+      // will return 0, which we count as false.
+      int int_value;
+      base::StringToInt(value, &int_value);
+      reversed_bypass_list_ = (value == "true" || int_value);
+    } else if (key == "NoProxyFor") {
+      AddHostList(PROXY_IGNORE_HOSTS, value);
+    } else if (key == "AuthMode") {
+      // Check for authentication, just so we can warn.
+      int mode;
+      base::StringToInt(value, &mode);
+      if (mode) {
+        // ProxyConfig does not support authentication parameters, but
+        // Chrome will prompt for the password later. So we ignore this.
+        LOG(WARNING) <<
+            "Proxy authentication parameters ignored, see bug 16709";
+      }
+    }
+  }
+
+  void ResolveIndirect(StringSetting key) {
+    string_map_type::iterator it = string_table_.find(key);
+    if (it != string_table_.end()) {
+      std::string value;
+      if (env_var_getter_->GetVar(it->second.c_str(), &value))
+        it->second = value;
+      else
+        string_table_.erase(it);
+    }
+  }
+
+  void ResolveIndirectList(StringListSetting key) {
+    strings_map_type::iterator it = strings_table_.find(key);
+    if (it != strings_table_.end()) {
+      std::string value;
+      if (!it->second.empty() &&
+          env_var_getter_->GetVar(it->second[0].c_str(), &value))
+        AddHostList(key, value);
+      else
+        strings_table_.erase(it);
+    }
+  }
+
+  // The settings in kioslaverc could occur in any order, but some affect
+  // others. Rather than read the whole file in and then query them in an
+  // order that allows us to handle that, we read the settings in whatever
+  // order they occur and do any necessary tweaking after we finish.
+  void ResolveModeEffects() {
+    if (indirect_manual_) {
+      ResolveIndirect(PROXY_HTTP_HOST);
+      ResolveIndirect(PROXY_HTTPS_HOST);
+      ResolveIndirect(PROXY_FTP_HOST);
+      ResolveIndirectList(PROXY_IGNORE_HOSTS);
+    }
+    if (auto_no_pac_) {
+      // Remove the PAC URL; we're not supposed to use it.
+      string_table_.erase(PROXY_AUTOCONF_URL);
+    }
+  }
+
+  // Reads kioslaverc one line at a time and calls AddKDESetting() to add
+  // each relevant name-value pair to the appropriate value table.
+  void UpdateCachedSettings() {
+    FilePath kioslaverc = kde_config_dir_.Append("kioslaverc");
+    file_util::ScopedFILE input(file_util::OpenFile(kioslaverc, "r"));
+    if (!input.get())
+      return;
+    ResetCachedSettings();
+    bool in_proxy_settings = false;
+    bool line_too_long = false;
+    char line[BUFFER_SIZE];
+    // fgets() will return NULL on EOF or error.
+    while (fgets(line, sizeof(line), input.get())) {
+      // fgets() guarantees the line will be properly terminated.
+      size_t length = strlen(line);
+      if (!length)
+        continue;
+      // This should be true even with CRLF endings.
+      if (line[length - 1] != '\n') {
+        line_too_long = true;
+        continue;
+      }
+      if (line_too_long) {
+        // The previous line had no line ending, but this done does. This is
+        // the end of the line that was too long, so warn here and skip it.
+        LOG(WARNING) << "skipped very long line in " << kioslaverc.value();
+        line_too_long = false;
+        continue;
+      }
+      // Remove the LF at the end, and the CR if there is one.
+      line[--length] = '\0';
+      if (length && line[length - 1] == '\r')
+        line[--length] = '\0';
+      // Now parse the line.
+      if (line[0] == '[') {
+        // Switching sections. All we care about is whether this is
+        // the (a?) proxy settings section, for both KDE3 and KDE4.
+        in_proxy_settings = !strncmp(line, "[Proxy Settings]", 16);
+      } else if (in_proxy_settings) {
+        // A regular line, in the (a?) proxy settings section.
+        char* split = strchr(line, '=');
+        // Skip this line if it does not contain an = sign.
+        if (!split)
+          continue;
+        // Split the line on the = and advance |split|.
+        *(split++) = 0;
+        std::string key = line;
+        std::string value = split;
+        TrimWhitespaceASCII(key, TRIM_ALL, &key);
+        TrimWhitespaceASCII(value, TRIM_ALL, &value);
+        // Skip this line if the key name is empty.
+        if (key.empty())
+          continue;
+        // Is the value name localized?
+        if (key[key.length() - 1] == ']') {
+          // Find the matching bracket.
+          length = key.rfind('[');
+          // Skip this line if the localization indicator is malformed.
+          if (length == std::string::npos)
+            continue;
+          // Trim the localization indicator off.
+          key.resize(length);
+          // Remove any resulting trailing whitespace.
+          TrimWhitespaceASCII(key, TRIM_TRAILING, &key);
+          // Skip this line if the key name is now empty.
+          if (key.empty())
+            continue;
+        }
+        // Now fill in the tables.
+        AddKDESetting(key, value);
+      }
+    }
+    if (ferror(input.get()))
+      LOG(ERROR) << "error reading " << kioslaverc.value();
+    ResolveModeEffects();
+  }
+
+  // This is the callback from the debounce timer.
+  void OnDebouncedNotification() {
+    DCHECK(MessageLoop::current() == file_loop_);
+    VLOG(1) << "inotify change notification for kioslaverc";
+    UpdateCachedSettings();
+    CHECK(notify_delegate_);
+    // Forward to a method on the proxy config service delegate object.
+    notify_delegate_->OnCheckProxyConfigSettings();
+  }
+
+  // Called by OnFileCanReadWithoutBlocking() on the file thread. Reads
+  // from the inotify file descriptor and starts up a debounce timer if
+  // an event for kioslaverc is seen.
+  void OnChangeNotification() {
+    DCHECK_GE(inotify_fd_,  0);
+    DCHECK(MessageLoop::current() == file_loop_);
+    char event_buf[(sizeof(inotify_event) + NAME_MAX + 1) * 4];
+    bool kioslaverc_touched = false;
+    ssize_t r;
+    while ((r = read(inotify_fd_, event_buf, sizeof(event_buf))) > 0) {
+      // inotify returns variable-length structures, which is why we have
+      // this strange-looking loop instead of iterating through an array.
+      char* event_ptr = event_buf;
+      while (event_ptr < event_buf + r) {
+        inotify_event* event = reinterpret_cast<inotify_event*>(event_ptr);
+        // The kernel always feeds us whole events.
+        CHECK_LE(event_ptr + sizeof(inotify_event), event_buf + r);
+        CHECK_LE(event->name + event->len, event_buf + r);
+        if (!strcmp(event->name, "kioslaverc"))
+          kioslaverc_touched = true;
+        // Advance the pointer just past the end of the filename.
+        event_ptr = event->name + event->len;
+      }
+      // We keep reading even if |kioslaverc_touched| is true to drain the
+      // inotify event queue.
+    }
+    if (!r)
+      // Instead of returning -1 and setting errno to EINVAL if there is not
+      // enough buffer space, older kernels (< 2.6.21) return 0. Simulate the
+      // new behavior (EINVAL) so we can reuse the code below.
+      errno = EINVAL;
+    if (errno != EAGAIN) {
+      PLOG(WARNING) << "error reading inotify file descriptor";
+      if (errno == EINVAL) {
+        // Our buffer is not large enough to read the next event. This should
+        // not happen (because its size is calculated to always be sufficiently
+        // large), but if it does we'd warn continuously since |inotify_fd_|
+        // would be forever ready to read. Close it and stop watching instead.
+        LOG(ERROR) << "inotify failure; no longer watching kioslaverc!";
+        inotify_watcher_.StopWatchingFileDescriptor();
+        close(inotify_fd_);
+        inotify_fd_ = -1;
+      }
+    }
+    if (kioslaverc_touched) {
+      // We don't use Reset() because the timer may not yet be running.
+      // (In that case Stop() is a no-op.)
+      debounce_timer_.Stop();
+      debounce_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
+          kDebounceTimeoutMilliseconds), this,
+          &SettingGetterImplKDE::OnDebouncedNotification);
+    }
+  }
+
+  typedef std::map<StringSetting, std::string> string_map_type;
+  typedef std::map<StringListSetting,
+                   std::vector<std::string> > strings_map_type;
+
+  int inotify_fd_;
+  base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_;
+  ProxyConfigServiceLinux::Delegate* notify_delegate_;
+  base::OneShotTimer<SettingGetterImplKDE> debounce_timer_;
+  FilePath kde_config_dir_;
+  bool indirect_manual_;
+  bool auto_no_pac_;
+  bool reversed_bypass_list_;
+  // We don't own |env_var_getter_|.  It's safe to hold a pointer to it, since
+  // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the
+  // same lifetime.
+  base::Environment* env_var_getter_;
+
+  // We cache these settings whenever we re-read the kioslaverc file.
+  string_map_type string_table_;
+  strings_map_type strings_table_;
+
+  // Message loop of the file thread, for reading kioslaverc. If NULL,
+  // just read it directly (for testing). We also handle inotify events
+  // on this thread.
+  MessageLoopForIO* file_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(SettingGetterImplKDE);
+};
+
+}  // namespace
+
+bool ProxyConfigServiceLinux::Delegate::GetProxyFromSettings(
+    SettingGetter::StringSetting host_key,
+    ProxyServer* result_server) {
+  std::string host;
+  if (!setting_getter_->GetString(host_key, &host) || host.empty()) {
+    // Unset or empty.
+    return false;
+  }
+  // Check for an optional port.
+  int port = 0;
+  SettingGetter::IntSetting port_key =
+      SettingGetter::HostSettingToPortSetting(host_key);
+  setting_getter_->GetInt(port_key, &port);
+  if (port != 0) {
+    // If a port is set and non-zero:
+    host += ":" + base::IntToString(port);
+  }
+
+  // gconf settings do not appear to distinguish between SOCKS version. We
+  // default to version 5. For more information on this policy decision, see:
+  // http://code.google.com/p/chromium/issues/detail?id=55912#c2
+  ProxyServer::Scheme scheme = (host_key == SettingGetter::PROXY_SOCKS_HOST) ?
+      ProxyServer::SCHEME_SOCKS5 : ProxyServer::SCHEME_HTTP;
+  host = FixupProxyHostScheme(scheme, host);
+  ProxyServer proxy_server = ProxyServer::FromURI(host,
+                                                  ProxyServer::SCHEME_HTTP);
+  if (proxy_server.is_valid()) {
+    *result_server = proxy_server;
+    return true;
+  }
+  return false;
+}
+
+bool ProxyConfigServiceLinux::Delegate::GetConfigFromSettings(
+    ProxyConfig* config) {
+  std::string mode;
+  if (!setting_getter_->GetString(SettingGetter::PROXY_MODE, &mode)) {
+    // We expect this to always be set, so if we don't see it then we
+    // probably have a gconf/gsettings problem, and so we don't have a valid
+    // proxy config.
+    return false;
+  }
+  if (mode == "none") {
+    // Specifically specifies no proxy.
+    return true;
+  }
+
+  if (mode == "auto") {
+    // Automatic proxy config.
+    std::string pac_url_str;
+    if (setting_getter_->GetString(SettingGetter::PROXY_AUTOCONF_URL,
+                                   &pac_url_str)) {
+      if (!pac_url_str.empty()) {
+        // If the PAC URL is actually a file path, then put file:// in front.
+        if (pac_url_str[0] == '/')
+          pac_url_str = "file://" + pac_url_str;
+        GURL pac_url(pac_url_str);
+        if (!pac_url.is_valid())
+          return false;
+        config->set_pac_url(pac_url);
+        return true;
+      }
+    }
+    config->set_auto_detect(true);
+    return true;
+  }
+
+  if (mode != "manual") {
+    // Mode is unrecognized.
+    return false;
+  }
+  bool use_http_proxy;
+  if (setting_getter_->GetBool(SettingGetter::PROXY_USE_HTTP_PROXY,
+                               &use_http_proxy)
+      && !use_http_proxy) {
+    // Another master switch for some reason. If set to false, then no
+    // proxy. But we don't panic if the key doesn't exist.
+    return true;
+  }
+
+  bool same_proxy = false;
+  // Indicates to use the http proxy for all protocols. This one may
+  // not exist (presumably on older versions); we assume false in that
+  // case.
+  setting_getter_->GetBool(SettingGetter::PROXY_USE_SAME_PROXY,
+                           &same_proxy);
+
+  ProxyServer proxy_for_http;
+  ProxyServer proxy_for_https;
+  ProxyServer proxy_for_ftp;
+  ProxyServer socks_proxy;  // (socks)
+
+  // This counts how many of the above ProxyServers were defined and valid.
+  size_t num_proxies_specified = 0;
+
+  // Extract the per-scheme proxies. If we failed to parse it, or no proxy was
+  // specified for the scheme, then the resulting ProxyServer will be invalid.
+  if (GetProxyFromSettings(SettingGetter::PROXY_HTTP_HOST, &proxy_for_http))
+    num_proxies_specified++;
+  if (GetProxyFromSettings(SettingGetter::PROXY_HTTPS_HOST, &proxy_for_https))
+    num_proxies_specified++;
+  if (GetProxyFromSettings(SettingGetter::PROXY_FTP_HOST, &proxy_for_ftp))
+    num_proxies_specified++;
+  if (GetProxyFromSettings(SettingGetter::PROXY_SOCKS_HOST, &socks_proxy))
+    num_proxies_specified++;
+
+  if (same_proxy) {
+    if (proxy_for_http.is_valid()) {
+      // Use the http proxy for all schemes.
+      config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+      config->proxy_rules().single_proxy = proxy_for_http;
+    }
+  } else if (num_proxies_specified > 0) {
+    if (socks_proxy.is_valid() && num_proxies_specified == 1) {
+      // If the only proxy specified was for SOCKS, use it for all schemes.
+      config->proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+      config->proxy_rules().single_proxy = socks_proxy;
+    } else {
+      // Otherwise use the indicate proxies per-scheme.
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+      config->proxy_rules().proxy_for_http = proxy_for_http;
+      config->proxy_rules().proxy_for_https = proxy_for_https;
+      config->proxy_rules().proxy_for_ftp = proxy_for_ftp;
+      config->proxy_rules().fallback_proxy = socks_proxy;
+    }
+  }
+
+  if (config->proxy_rules().empty()) {
+    // Manual mode but we couldn't parse any rules.
+    return false;
+  }
+
+  // Check for authentication, just so we can warn.
+  bool use_auth = false;
+  setting_getter_->GetBool(SettingGetter::PROXY_USE_AUTHENTICATION,
+                           &use_auth);
+  if (use_auth) {
+    // ProxyConfig does not support authentication parameters, but
+    // Chrome will prompt for the password later. So we ignore
+    // /system/http_proxy/*auth* settings.
+    LOG(WARNING) << "Proxy authentication parameters ignored, see bug 16709";
+  }
+
+  // Now the bypass list.
+  std::vector<std::string> ignore_hosts_list;
+  config->proxy_rules().bypass_rules.Clear();
+  if (setting_getter_->GetStringList(SettingGetter::PROXY_IGNORE_HOSTS,
+                                     &ignore_hosts_list)) {
+    std::vector<std::string>::const_iterator it(ignore_hosts_list.begin());
+    for (; it != ignore_hosts_list.end(); ++it) {
+      if (setting_getter_->MatchHostsUsingSuffixMatching()) {
+        config->proxy_rules().bypass_rules.
+            AddRuleFromStringUsingSuffixMatching(*it);
+      } else {
+        config->proxy_rules().bypass_rules.AddRuleFromString(*it);
+      }
+    }
+  }
+  // Note that there are no settings with semantics corresponding to
+  // bypass of local names in GNOME. In KDE, "<local>" is supported
+  // as a hostname rule.
+
+  // KDE allows one to reverse the bypass rules.
+  config->proxy_rules().reverse_bypass =
+      setting_getter_->BypassListIsReversed();
+
+  return true;
+}
+
+ProxyConfigServiceLinux::Delegate::Delegate(base::Environment* env_var_getter)
+    : env_var_getter_(env_var_getter) {
+  // Figure out which SettingGetterImpl to use, if any.
+  switch (base::nix::GetDesktopEnvironment(env_var_getter)) {
+    case base::nix::DESKTOP_ENVIRONMENT_GNOME:
+    case base::nix::DESKTOP_ENVIRONMENT_UNITY:
+#if defined(USE_GIO)
+      {
+        scoped_ptr<SettingGetterImplGSettings> gs_getter(
+            new SettingGetterImplGSettings());
+        // We have to load symbols and check the GNOME version in use to decide
+        // if we should use the gsettings getter. See LoadAndCheckVersion().
+        if (gs_getter->LoadAndCheckVersion(env_var_getter))
+          setting_getter_.reset(gs_getter.release());
+      }
+#endif
+#if defined(USE_GCONF)
+      // Fall back on gconf if gsettings is unavailable or incorrect.
+      if (!setting_getter_.get())
+        setting_getter_.reset(new SettingGetterImplGConf());
+#endif
+      break;
+    case base::nix::DESKTOP_ENVIRONMENT_KDE3:
+    case base::nix::DESKTOP_ENVIRONMENT_KDE4:
+      setting_getter_.reset(new SettingGetterImplKDE(env_var_getter));
+      break;
+    case base::nix::DESKTOP_ENVIRONMENT_XFCE:
+    case base::nix::DESKTOP_ENVIRONMENT_OTHER:
+      break;
+  }
+}
+
+ProxyConfigServiceLinux::Delegate::Delegate(
+    base::Environment* env_var_getter, SettingGetter* setting_getter)
+    : env_var_getter_(env_var_getter), setting_getter_(setting_getter) {
+}
+
+void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig(
+    base::SingleThreadTaskRunner* glib_thread_task_runner,
+    base::SingleThreadTaskRunner* io_thread_task_runner,
+    MessageLoopForIO* file_loop) {
+  // We should be running on the default glib main loop thread right
+  // now. gconf can only be accessed from this thread.
+  DCHECK(glib_thread_task_runner->BelongsToCurrentThread());
+  glib_thread_task_runner_ = glib_thread_task_runner;
+  io_thread_task_runner_ = io_thread_task_runner;
+
+  // If we are passed a NULL |io_thread_task_runner| or |file_loop|,
+  // then we don't set up proxy setting change notifications. This
+  // should not be the usual case but is intended to simplify test
+  // setups.
+  if (!io_thread_task_runner_ || !file_loop)
+    VLOG(1) << "Monitoring of proxy setting changes is disabled";
+
+  // Fetch and cache the current proxy config. The config is left in
+  // cached_config_, where GetLatestProxyConfig() running on the IO thread
+  // will expect to find it. This is safe to do because we return
+  // before this ProxyConfigServiceLinux is passed on to
+  // the ProxyService.
+
+  // Note: It would be nice to prioritize environment variables
+  // and only fall back to gconf if env vars were unset. But
+  // gnome-terminal "helpfully" sets http_proxy and no_proxy, and it
+  // does so even if the proxy mode is set to auto, which would
+  // mislead us.
+
+  bool got_config = false;
+  if (setting_getter_.get() &&
+      setting_getter_->Init(glib_thread_task_runner, file_loop) &&
+      GetConfigFromSettings(&cached_config_)) {
+    cached_config_.set_id(1);  // Mark it as valid.
+    cached_config_.set_source(setting_getter_->GetConfigSource());
+    VLOG(1) << "Obtained proxy settings from "
+            << ProxyConfigSourceToString(cached_config_.source());
+
+    // If gconf proxy mode is "none", meaning direct, then we take
+    // that to be a valid config and will not check environment
+    // variables. The alternative would have been to look for a proxy
+    // whereever we can find one.
+    got_config = true;
+
+    // Keep a copy of the config for use from this thread for
+    // comparison with updated settings when we get notifications.
+    reference_config_ = cached_config_;
+    reference_config_.set_id(1);  // Mark it as valid.
+
+    // We only set up notifications if we have IO and file loops available.
+    // We do this after getting the initial configuration so that we don't have
+    // to worry about cancelling it if the initial fetch above fails. Note that
+    // setting up notifications has the side effect of simulating a change, so
+    // that we won't lose any updates that may have happened after the initial
+    // fetch and before setting up notifications. We'll detect the common case
+    // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it.
+    if (io_thread_task_runner && file_loop) {
+      scoped_refptr<base::SingleThreadTaskRunner> required_loop =
+          setting_getter_->GetNotificationTaskRunner();
+      if (!required_loop || required_loop->BelongsToCurrentThread()) {
+        // In this case we are already on an acceptable thread.
+        SetUpNotifications();
+      } else {
+        // Post a task to set up notifications. We don't wait for success.
+        required_loop->PostTask(FROM_HERE, base::Bind(
+            &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this));
+      }
+    }
+  }
+
+  if (!got_config) {
+    // We fall back on environment variables.
+    //
+    // Consulting environment variables doesn't need to be done from the
+    // default glib main loop, but it's a tiny enough amount of work.
+    if (GetConfigFromEnv(&cached_config_)) {
+      cached_config_.set_source(PROXY_CONFIG_SOURCE_ENV);
+      cached_config_.set_id(1);  // Mark it as valid.
+      VLOG(1) << "Obtained proxy settings from environment variables";
+    }
+  }
+}
+
+// Depending on the SettingGetter in use, this method will be called
+// on either the UI thread (GConf) or the file thread (KDE).
+void ProxyConfigServiceLinux::Delegate::SetUpNotifications() {
+  scoped_refptr<base::SingleThreadTaskRunner> required_loop =
+      setting_getter_->GetNotificationTaskRunner();
+  DCHECK(!required_loop || required_loop->BelongsToCurrentThread());
+  if (!setting_getter_->SetUpNotifications(this))
+    LOG(ERROR) << "Unable to set up proxy configuration change notifications";
+}
+
+void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
+ProxyConfigService::ConfigAvailability
+    ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig(
+        ProxyConfig* config) {
+  // This is called from the IO thread.
+  DCHECK(!io_thread_task_runner_ ||
+         io_thread_task_runner_->BelongsToCurrentThread());
+
+  // Simply return the last proxy configuration that glib_default_loop
+  // notified us of.
+  if (cached_config_.is_valid()) {
+    *config = cached_config_;
+  } else {
+    *config = ProxyConfig::CreateDirect();
+    config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED);
+  }
+
+  // We return CONFIG_VALID to indicate that *config was filled in. It is always
+  // going to be available since we initialized eagerly on the UI thread.
+  // TODO(eroman): do lazy initialization instead, so we no longer need
+  //               to construct ProxyConfigServiceLinux on the UI thread.
+  //               In which case, we may return false here.
+  return CONFIG_VALID;
+}
+
+// Depending on the SettingGetter in use, this method will be called
+// on either the UI thread (GConf) or the file thread (KDE).
+void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() {
+  scoped_refptr<base::SingleThreadTaskRunner> required_loop =
+      setting_getter_->GetNotificationTaskRunner();
+  DCHECK(!required_loop || required_loop->BelongsToCurrentThread());
+  ProxyConfig new_config;
+  bool valid = GetConfigFromSettings(&new_config);
+  if (valid)
+    new_config.set_id(1);  // mark it as valid
+
+  // See if it is different from what we had before.
+  if (new_config.is_valid() != reference_config_.is_valid() ||
+      !new_config.Equals(reference_config_)) {
+    // Post a task to the IO thread with the new configuration, so it can
+    // update |cached_config_|.
+    io_thread_task_runner_->PostTask(FROM_HERE, base::Bind(
+        &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig,
+        this, new_config));
+    // Update the thread-private copy in |reference_config_| as well.
+    reference_config_ = new_config;
+  } else {
+    VLOG(1) << "Detected no-op change to proxy settings. Doing nothing.";
+  }
+}
+
+void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig(
+    const ProxyConfig& new_config) {
+  DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
+  VLOG(1) << "Proxy configuration changed";
+  cached_config_ = new_config;
+  FOR_EACH_OBSERVER(
+      Observer, observers_,
+      OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID));
+}
+
+void ProxyConfigServiceLinux::Delegate::PostDestroyTask() {
+  if (!setting_getter_.get())
+    return;
+  scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop =
+      setting_getter_->GetNotificationTaskRunner();
+  if (!shutdown_loop || shutdown_loop->BelongsToCurrentThread()) {
+    // Already on the right thread, call directly.
+    // This is the case for the unittests.
+    OnDestroy();
+  } else {
+    // Post to shutdown thread. Note that on browser shutdown, we may quit
+    // this MessageLoop and exit the program before ever running this.
+    shutdown_loop->PostTask(FROM_HERE, base::Bind(
+        &ProxyConfigServiceLinux::Delegate::OnDestroy, this));
+  }
+}
+void ProxyConfigServiceLinux::Delegate::OnDestroy() {
+  scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop =
+      setting_getter_->GetNotificationTaskRunner();
+  DCHECK(!shutdown_loop || shutdown_loop->BelongsToCurrentThread());
+  setting_getter_->ShutDown();
+}
+
+ProxyConfigServiceLinux::ProxyConfigServiceLinux()
+    : delegate_(new Delegate(base::Environment::Create())) {
+}
+
+ProxyConfigServiceLinux::~ProxyConfigServiceLinux() {
+  delegate_->PostDestroyTask();
+}
+
+ProxyConfigServiceLinux::ProxyConfigServiceLinux(
+    base::Environment* env_var_getter)
+    : delegate_(new Delegate(env_var_getter)) {
+}
+
+ProxyConfigServiceLinux::ProxyConfigServiceLinux(
+    base::Environment* env_var_getter, SettingGetter* setting_getter)
+    : delegate_(new Delegate(env_var_getter, setting_getter)) {
+}
+
+void ProxyConfigServiceLinux::AddObserver(Observer* observer) {
+  delegate_->AddObserver(observer);
+}
+
+void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) {
+  delegate_->RemoveObserver(observer);
+}
+
+ProxyConfigService::ConfigAvailability
+    ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) {
+  return delegate_->GetLatestProxyConfig(config);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_linux.h b/src/net/proxy/proxy_config_service_linux.h
new file mode 100644
index 0000000..8d46d99
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_linux.h
@@ -0,0 +1,309 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_PROXY_CONFIG_SERVICE_LINUX_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_LINUX_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/environment.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/proxy/proxy_server.h"
+
+class MessageLoopForIO;
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace net {
+
+// Implementation of ProxyConfigService that retrieves the system proxy
+// settings from environment variables, gconf, gsettings, or kioslaverc (KDE).
+class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService {
+ public:
+
+  // Forward declaration of Delegate.
+  class Delegate;
+
+  class SettingGetter {
+   public:
+    // Buffer size used in some implementations of this class when reading
+    // files. Defined here so unit tests can construct worst-case inputs.
+    static const size_t BUFFER_SIZE = 512;
+
+    SettingGetter() {}
+    virtual ~SettingGetter() {}
+
+    // Initializes the class: obtains a gconf/gsettings client, or simulates
+    // one, in the concrete implementations. Returns true on success. Must be
+    // called before using other methods, and should be called on the thread
+    // running the glib main loop.
+    // One of |glib_thread_task_runner| and |file_loop| will be used for
+    // gconf/gsettings calls or reading necessary files, depending on the
+    // implementation.
+    virtual bool Init(base::SingleThreadTaskRunner* glib_thread_task_runner,
+                      MessageLoopForIO* file_loop) = 0;
+
+    // Releases the gconf/gsettings client, which clears cached directories and
+    // stops notifications.
+    virtual void ShutDown() = 0;
+
+    // Requests notification of gconf/gsettings changes for proxy
+    // settings. Returns true on success.
+    virtual bool SetUpNotifications(Delegate* delegate) = 0;
+
+    // Returns the message loop for the thread on which this object
+    // handles notifications, and also on which it must be destroyed.
+    // Returns NULL if it does not matter.
+    virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() = 0;
+
+    // Returns the source of proxy settings.
+    virtual ProxyConfigSource GetConfigSource() = 0;
+
+    // These are all the values that can be fetched. We used to just use the
+    // corresponding paths in gconf for these, but gconf is now obsolete and
+    // in the future we'll be using mostly gsettings/kioslaverc so we
+    // enumerate them instead to avoid unnecessary string operations.
+    enum StringSetting {
+      PROXY_MODE,
+      PROXY_AUTOCONF_URL,
+      PROXY_HTTP_HOST,
+      PROXY_HTTPS_HOST,
+      PROXY_FTP_HOST,
+      PROXY_SOCKS_HOST,
+    };
+    enum BoolSetting {
+      PROXY_USE_HTTP_PROXY,
+      PROXY_USE_SAME_PROXY,
+      PROXY_USE_AUTHENTICATION,
+    };
+    enum IntSetting {
+      PROXY_HTTP_PORT,
+      PROXY_HTTPS_PORT,
+      PROXY_FTP_PORT,
+      PROXY_SOCKS_PORT,
+    };
+    enum StringListSetting {
+      PROXY_IGNORE_HOSTS,
+    };
+
+    // Given a PROXY_*_HOST value, return the corresponding PROXY_*_PORT value.
+    static IntSetting HostSettingToPortSetting(StringSetting host) {
+      switch (host) {
+        case PROXY_HTTP_HOST:
+          return PROXY_HTTP_PORT;
+        case PROXY_HTTPS_HOST:
+          return PROXY_HTTPS_PORT;
+        case PROXY_FTP_HOST:
+          return PROXY_FTP_PORT;
+        case PROXY_SOCKS_HOST:
+          return PROXY_SOCKS_PORT;
+        default:
+          NOTREACHED();
+          return PROXY_HTTP_PORT;  // Placate compiler.
+      }
+    }
+
+    // Gets a string type value from the data source and stores it in
+    // |*result|. Returns false if the key is unset or on error. Must only be
+    // called after a successful call to Init(), and not after a failed call
+    // to SetUpNotifications() or after calling Release().
+    virtual bool GetString(StringSetting key, std::string* result) = 0;
+    // Same thing for a bool typed value.
+    virtual bool GetBool(BoolSetting key, bool* result) = 0;
+    // Same for an int typed value.
+    virtual bool GetInt(IntSetting key, int* result) = 0;
+    // And for a string list.
+    virtual bool GetStringList(StringListSetting key,
+                               std::vector<std::string>* result) = 0;
+
+    // Returns true if the bypass list should be interpreted as a proxy
+    // whitelist rather than blacklist. (This is KDE-specific.)
+    virtual bool BypassListIsReversed() = 0;
+
+    // Returns true if the bypass rules should be interpreted as
+    // suffix-matching rules.
+    virtual bool MatchHostsUsingSuffixMatching() = 0;
+
+   private:
+    DISALLOW_COPY_AND_ASSIGN(SettingGetter);
+  };
+
+  // ProxyConfigServiceLinux is created on the UI thread, and
+  // SetUpAndFetchInitialConfig() is immediately called to synchronously
+  // fetch the original configuration and set up change notifications on
+  // the UI thread.
+  //
+  // Past that point, it is accessed periodically through the
+  // ProxyConfigService interface (GetLatestProxyConfig, AddObserver,
+  // RemoveObserver) from the IO thread.
+  //
+  // Setting change notification callbacks can occur at any time and are
+  // run on either the UI thread (gconf/gsettings) or the file thread
+  // (KDE). The new settings are fetched on that thread, and the resulting
+  // proxy config is posted to the IO thread through
+  // Delegate::SetNewProxyConfig(). We then notify observers on the IO
+  // thread of the configuration change.
+  //
+  // ProxyConfigServiceLinux is deleted from the IO thread.
+  //
+  // The substance of the ProxyConfigServiceLinux implementation is
+  // wrapped in the Delegate ref counted class. On deleting the
+  // ProxyConfigServiceLinux, Delegate::OnDestroy() is posted to either
+  // the UI thread (gconf/gsettings) or the file thread (KDE) where change
+  // notifications will be safely stopped before releasing Delegate.
+
+  class Delegate : public base::RefCountedThreadSafe<Delegate> {
+   public:
+    // Constructor receives env var getter implementation to use, and
+    // takes ownership of it. This is the normal constructor.
+    explicit Delegate(base::Environment* env_var_getter);
+    // Constructor receives setting and env var getter implementations
+    // to use, and takes ownership of them. Used for testing.
+    Delegate(base::Environment* env_var_getter, SettingGetter* setting_getter);
+
+    // Synchronously obtains the proxy configuration. If gconf,
+    // gsettings, or kioslaverc are used, also enables notifications for
+    // setting changes. gconf/gsettings must only be accessed from the
+    // thread running the default glib main loop, and so this method
+    // must be called from the UI thread. The message loop for the IO
+    // thread is specified so that notifications can post tasks to it
+    // (and for assertions). The message loop for the file thread is
+    // used to read any files needed to determine proxy settings.
+    void SetUpAndFetchInitialConfig(
+        base::SingleThreadTaskRunner* glib_thread_task_runner,
+        base::SingleThreadTaskRunner* io_thread_task_runner,
+        MessageLoopForIO* file_loop);
+
+    // Handler for setting change notifications: fetches a new proxy
+    // configuration from settings, and if this config is different
+    // than what we had before, posts a task to have it stored in
+    // cached_config_.
+    // Left public for simplicity.
+    void OnCheckProxyConfigSettings();
+
+    // Called from IO thread.
+    void AddObserver(Observer* observer);
+    void RemoveObserver(Observer* observer);
+    ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
+        ProxyConfig* config);
+
+    // Posts a call to OnDestroy() to the UI or FILE thread, depending on the
+    // setting getter in use. Called from ProxyConfigServiceLinux's destructor.
+    void PostDestroyTask();
+    // Safely stops change notifications. Posted to either the UI or FILE
+    // thread, depending on the setting getter in use.
+    void OnDestroy();
+
+   private:
+    friend class base::RefCountedThreadSafe<Delegate>;
+
+    ~Delegate();
+
+    // Obtains an environment variable's value. Parses a proxy server
+    // specification from it and puts it in result. Returns true if the
+    // requested variable is defined and the value valid.
+    bool GetProxyFromEnvVarForScheme(const char* variable,
+                                     ProxyServer::Scheme scheme,
+                                     ProxyServer* result_server);
+    // As above but with scheme set to HTTP, for convenience.
+    bool GetProxyFromEnvVar(const char* variable, ProxyServer* result_server);
+    // Fills proxy config from environment variables. Returns true if
+    // variables were found and the configuration is valid.
+    bool GetConfigFromEnv(ProxyConfig* config);
+
+    // Obtains host and port config settings and parses a proxy server
+    // specification from it and puts it in result. Returns true if the
+    // requested variable is defined and the value valid.
+    bool GetProxyFromSettings(SettingGetter::StringSetting host_key,
+                              ProxyServer* result_server);
+    // Fills proxy config from settings. Returns true if settings were found
+    // and the configuration is valid.
+    bool GetConfigFromSettings(ProxyConfig* config);
+
+    // This method is posted from the UI thread to the IO thread to
+    // carry the new config information.
+    void SetNewProxyConfig(const ProxyConfig& new_config);
+
+    // This method is run on the getter's notification thread.
+    void SetUpNotifications();
+
+    scoped_ptr<base::Environment> env_var_getter_;
+    scoped_ptr<SettingGetter> setting_getter_;
+
+    // Cached proxy configuration, to be returned by
+    // GetLatestProxyConfig. Initially populated from the UI thread, but
+    // afterwards only accessed from the IO thread.
+    ProxyConfig cached_config_;
+
+    // A copy kept on the UI thread of the last seen proxy config, so as
+    // to avoid posting a call to SetNewProxyConfig when we get a
+    // notification but the config has not actually changed.
+    ProxyConfig reference_config_;
+
+    // The task runner for the glib thread, aka main browser thread. This thread
+    // is where we run the glib main loop (see base/message_pump_glib.h). It is
+    // the glib default loop in the sense that it runs the glib default context:
+    // as in the context where sources are added by g_timeout_add and
+    // g_idle_add, and returned by g_main_context_default. gconf uses glib
+    // timeouts and idles and possibly other callbacks that will all be
+    // dispatched on this thread. Since gconf is not thread safe, any use of
+    // gconf must be done on the thread running this loop.
+    scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner_;
+    // Task runner for the IO thread. GetLatestProxyConfig() is called from
+    // the thread running this loop.
+    scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
+
+    ObserverList<Observer> observers_;
+
+    DISALLOW_COPY_AND_ASSIGN(Delegate);
+  };
+
+  // Thin wrapper shell around Delegate.
+
+  // Usual constructor
+  ProxyConfigServiceLinux();
+  // For testing: take alternate setting and env var getter implementations.
+  explicit ProxyConfigServiceLinux(base::Environment* env_var_getter);
+  ProxyConfigServiceLinux(base::Environment* env_var_getter,
+                          SettingGetter* setting_getter);
+
+  virtual ~ProxyConfigServiceLinux();
+
+  void SetupAndFetchInitialConfig(
+      base::SingleThreadTaskRunner* glib_thread_task_runner,
+      base::SingleThreadTaskRunner* io_thread_task_runner,
+      MessageLoopForIO* file_loop) {
+    delegate_->SetUpAndFetchInitialConfig(glib_thread_task_runner,
+                                          io_thread_task_runner, file_loop);
+  }
+  void OnCheckProxyConfigSettings() {
+    delegate_->OnCheckProxyConfigSettings();
+  }
+
+  // ProxyConfigService methods:
+  // Called from IO thread.
+  virtual void AddObserver(Observer* observer) OVERRIDE;
+  virtual void RemoveObserver(Observer* observer) OVERRIDE;
+  virtual ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
+      ProxyConfig* config) OVERRIDE;
+
+ private:
+  scoped_refptr<Delegate> delegate_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceLinux);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_LINUX_H_
diff --git a/src/net/proxy/proxy_config_service_linux_unittest.cc b/src/net/proxy/proxy_config_service_linux_unittest.cc
new file mode 100644
index 0000000..7862141
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_linux_unittest.cc
@@ -0,0 +1,1616 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_config_service_linux.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace net {
+namespace {
+
+// Set of values for all environment variables that we might
+// query. NULL represents an unset variable.
+struct EnvVarValues {
+  // The strange capitalization is so that the field matches the
+  // environment variable name exactly.
+  const char *DESKTOP_SESSION, *HOME,
+      *KDEHOME, *KDE_SESSION_VERSION,
+      *auto_proxy, *all_proxy,
+      *http_proxy, *https_proxy, *ftp_proxy,
+      *SOCKS_SERVER, *SOCKS_VERSION,
+      *no_proxy;
+};
+
+// Undo macro pollution from GDK includes (from message_loop.h).
+#undef TRUE
+#undef FALSE
+
+// So as to distinguish between an unset gconf boolean variable and
+// one that is false.
+enum BoolSettingValue {
+  UNSET = 0, TRUE, FALSE
+};
+
+// Set of values for all gconf settings that we might query.
+struct GConfValues {
+  // strings
+  const char *mode, *autoconfig_url,
+      *http_host, *secure_host, *ftp_host, *socks_host;
+  // integers
+  int http_port, secure_port, ftp_port, socks_port;
+  // booleans
+  BoolSettingValue use_proxy, same_proxy, use_auth;
+  // string list
+  std::vector<std::string> ignore_hosts;
+};
+
+// Mapping from a setting name to the location of the corresponding
+// value (inside a EnvVarValues or GConfValues struct).
+template<typename key_type, typename value_type>
+struct SettingsTable {
+  typedef std::map<key_type, value_type*> map_type;
+
+  // Gets the value from its location
+  value_type Get(key_type key) {
+    typename map_type::const_iterator it = settings.find(key);
+    // In case there's a typo or the unittest becomes out of sync.
+    CHECK(it != settings.end()) << "key " << key << " not found";
+    value_type* value_ptr = it->second;
+    return *value_ptr;
+  }
+
+  map_type settings;
+};
+
+class MockEnvironment : public base::Environment {
+ public:
+  MockEnvironment() {
+#define ENTRY(x) table[#x] = &values.x
+    ENTRY(DESKTOP_SESSION);
+    ENTRY(HOME);
+    ENTRY(KDEHOME);
+    ENTRY(KDE_SESSION_VERSION);
+    ENTRY(auto_proxy);
+    ENTRY(all_proxy);
+    ENTRY(http_proxy);
+    ENTRY(https_proxy);
+    ENTRY(ftp_proxy);
+    ENTRY(no_proxy);
+    ENTRY(SOCKS_SERVER);
+    ENTRY(SOCKS_VERSION);
+#undef ENTRY
+    Reset();
+  }
+
+  // Zeroes all environment values.
+  void Reset() {
+    EnvVarValues zero_values = { 0 };
+    values = zero_values;
+  }
+
+  // Begin base::Environment implementation.
+  virtual bool GetVar(const char* variable_name, std::string* result) OVERRIDE {
+    std::map<std::string, const char**>::iterator it =
+        table.find(variable_name);
+    if (it != table.end() && *(it->second) != NULL) {
+      // Note that the variable may be defined but empty.
+      *result = *(it->second);
+      return true;
+    }
+    return false;
+  }
+
+  virtual bool SetVar(const char* variable_name, const std::string& new_value)
+      OVERRIDE {
+    ADD_FAILURE();
+    return false;
+  }
+
+  virtual bool UnSetVar(const char* variable_name) OVERRIDE {
+    ADD_FAILURE();
+    return false;
+  }
+  // End base::Environment implementation.
+
+  // Intentionally public, for convenience when setting up a test.
+  EnvVarValues values;
+
+ private:
+  std::map<std::string, const char**> table;
+};
+
+class MockSettingGetter
+    : public ProxyConfigServiceLinux::SettingGetter {
+ public:
+  typedef ProxyConfigServiceLinux::SettingGetter SettingGetter;
+  MockSettingGetter() {
+#define ENTRY(key, field) \
+      strings_table.settings[SettingGetter::key] = &values.field
+    ENTRY(PROXY_MODE, mode);
+    ENTRY(PROXY_AUTOCONF_URL, autoconfig_url);
+    ENTRY(PROXY_HTTP_HOST, http_host);
+    ENTRY(PROXY_HTTPS_HOST, secure_host);
+    ENTRY(PROXY_FTP_HOST, ftp_host);
+    ENTRY(PROXY_SOCKS_HOST, socks_host);
+#undef ENTRY
+#define ENTRY(key, field) \
+      ints_table.settings[SettingGetter::key] = &values.field
+    ENTRY(PROXY_HTTP_PORT, http_port);
+    ENTRY(PROXY_HTTPS_PORT, secure_port);
+    ENTRY(PROXY_FTP_PORT, ftp_port);
+    ENTRY(PROXY_SOCKS_PORT, socks_port);
+#undef ENTRY
+#define ENTRY(key, field) \
+      bools_table.settings[SettingGetter::key] = &values.field
+    ENTRY(PROXY_USE_HTTP_PROXY, use_proxy);
+    ENTRY(PROXY_USE_SAME_PROXY, same_proxy);
+    ENTRY(PROXY_USE_AUTHENTICATION, use_auth);
+#undef ENTRY
+    string_lists_table.settings[SettingGetter::PROXY_IGNORE_HOSTS] =
+        &values.ignore_hosts;
+    Reset();
+  }
+
+  // Zeros all environment values.
+  void Reset() {
+    GConfValues zero_values = { 0 };
+    values = zero_values;
+  }
+
+  virtual bool Init(base::SingleThreadTaskRunner* glib_thread_task_runner,
+                    MessageLoopForIO* file_loop) OVERRIDE {
+    return true;
+  }
+
+  virtual void ShutDown() OVERRIDE {}
+
+  virtual bool SetUpNotifications(ProxyConfigServiceLinux::Delegate* delegate)
+      OVERRIDE {
+    return true;
+  }
+
+  virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() OVERRIDE {
+    return NULL;
+  }
+
+  virtual ProxyConfigSource GetConfigSource() OVERRIDE {
+    return PROXY_CONFIG_SOURCE_TEST;
+  }
+
+  virtual bool GetString(StringSetting key, std::string* result) OVERRIDE {
+    const char* value = strings_table.Get(key);
+    if (value) {
+      *result = value;
+      return true;
+    }
+    return false;
+  }
+
+  virtual bool GetBool(BoolSetting key, bool* result) OVERRIDE {
+    BoolSettingValue value = bools_table.Get(key);
+    switch (value) {
+    case UNSET:
+      return false;
+    case TRUE:
+      *result = true;
+      break;
+    case FALSE:
+      *result = false;
+    }
+    return true;
+  }
+
+  virtual bool GetInt(IntSetting key, int* result) OVERRIDE {
+    // We don't bother to distinguish unset keys from 0 values.
+    *result = ints_table.Get(key);
+    return true;
+  }
+
+  virtual bool GetStringList(StringListSetting key,
+                             std::vector<std::string>* result) OVERRIDE {
+    *result = string_lists_table.Get(key);
+    // We don't bother to distinguish unset keys from empty lists.
+    return !result->empty();
+  }
+
+  virtual bool BypassListIsReversed() OVERRIDE {
+    return false;
+  }
+
+  virtual bool MatchHostsUsingSuffixMatching() OVERRIDE {
+    return false;
+  }
+
+  // Intentionally public, for convenience when setting up a test.
+  GConfValues values;
+
+ private:
+  SettingsTable<StringSetting, const char*> strings_table;
+  SettingsTable<BoolSetting, BoolSettingValue> bools_table;
+  SettingsTable<IntSetting, int> ints_table;
+  SettingsTable<StringListSetting,
+                std::vector<std::string> > string_lists_table;
+};
+
+}  // namespace
+}  // namespace net
+
+// This helper class runs ProxyConfigServiceLinux::GetLatestProxyConfig() on
+// the IO thread and synchronously waits for the result.
+// Some code duplicated from proxy_script_fetcher_unittest.cc.
+class SynchConfigGetter {
+ public:
+  // Takes ownership of |config_service|.
+  explicit SynchConfigGetter(net::ProxyConfigServiceLinux* config_service)
+      : event_(false, false),
+        io_thread_("IO_Thread"),
+        config_service_(config_service) {
+    // Start an IO thread.
+    base::Thread::Options options;
+    options.message_loop_type = MessageLoop::TYPE_IO;
+    io_thread_.StartWithOptions(options);
+
+    // Make sure the thread started.
+    io_thread_.message_loop()->PostTask(FROM_HERE,
+        base::Bind(&SynchConfigGetter::Init, base::Unretained(this)));
+    Wait();
+  }
+
+  ~SynchConfigGetter() {
+    // Let the config service post a destroy message to the IO thread
+    // before cleaning up that thread.
+    delete config_service_;
+    // Clean up the IO thread.
+    io_thread_.message_loop()->PostTask(FROM_HERE,
+        base::Bind(&SynchConfigGetter::CleanUp, base::Unretained(this)));
+    Wait();
+  }
+
+  // Does gconf setup and initial fetch of the proxy config,
+  // all on the calling thread (meant to be the thread with the
+  // default glib main loop, which is the UI thread).
+  void SetupAndInitialFetch() {
+    MessageLoop* file_loop = io_thread_.message_loop();
+    DCHECK_EQ(MessageLoop::TYPE_IO, file_loop->type());
+    // We pass the mock IO thread as both the IO and file threads.
+    config_service_->SetupAndFetchInitialConfig(
+        base::MessageLoopProxy::current(), io_thread_.message_loop_proxy(),
+        static_cast<MessageLoopForIO*>(file_loop));
+  }
+  // Synchronously gets the proxy config.
+  net::ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig(
+      net::ProxyConfig* config) {
+    io_thread_.message_loop()->PostTask(FROM_HERE,
+        base::Bind(&SynchConfigGetter::GetLatestConfigOnIOThread,
+                   base::Unretained(this)));
+    Wait();
+    *config = proxy_config_;
+    return get_latest_config_result_;
+  }
+
+ private:
+  // [Runs on |io_thread_|]
+  void Init() {
+    event_.Signal();
+  }
+
+  // Calls GetLatestProxyConfig, running on |io_thread_| Signals |event_|
+  // on completion.
+  void GetLatestConfigOnIOThread() {
+    get_latest_config_result_ =
+        config_service_->GetLatestProxyConfig(&proxy_config_);
+    event_.Signal();
+  }
+
+  // [Runs on |io_thread_|] Signals |event_| on cleanup completion.
+  void CleanUp() {
+    MessageLoop::current()->RunUntilIdle();
+    event_.Signal();
+  }
+
+  void Wait() {
+    event_.Wait();
+    event_.Reset();
+  }
+
+  base::WaitableEvent event_;
+  base::Thread io_thread_;
+
+  net::ProxyConfigServiceLinux* config_service_;
+
+  // The config obtained by |io_thread_| and read back by the main
+  // thread.
+  net::ProxyConfig proxy_config_;
+
+  // Return value from GetLatestProxyConfig().
+  net::ProxyConfigService::ConfigAvailability get_latest_config_result_;
+};
+
+namespace net {
+
+// This test fixture is only really needed for the KDEConfigParser test case,
+// but all the test cases with the same prefix ("ProxyConfigServiceLinuxTest")
+// must use the same test fixture class (also "ProxyConfigServiceLinuxTest").
+class ProxyConfigServiceLinuxTest : public PlatformTest {
+ protected:
+  virtual void SetUp() OVERRIDE {
+    PlatformTest::SetUp();
+    // Set up a temporary KDE home directory.
+    std::string prefix("ProxyConfigServiceLinuxTest_user_home");
+    file_util::CreateNewTempDirectory(prefix, &user_home_);
+    kde_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde"));
+    FilePath path = kde_home_.Append(FILE_PATH_LITERAL("share"));
+    path = path.Append(FILE_PATH_LITERAL("config"));
+    file_util::CreateDirectory(path);
+    kioslaverc_ = path.Append(FILE_PATH_LITERAL("kioslaverc"));
+    // Set up paths but do not create the directory for .kde4.
+    kde4_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde4"));
+    path = kde4_home_.Append(FILE_PATH_LITERAL("share"));
+    kde4_config_ = path.Append(FILE_PATH_LITERAL("config"));
+    kioslaverc4_ = kde4_config_.Append(FILE_PATH_LITERAL("kioslaverc"));
+  }
+
+  virtual void TearDown() OVERRIDE {
+    // Delete the temporary KDE home directory.
+    file_util::Delete(user_home_, true);
+    PlatformTest::TearDown();
+  }
+
+  FilePath user_home_;
+  // KDE3 paths.
+  FilePath kde_home_;
+  FilePath kioslaverc_;
+  // KDE4 paths.
+  FilePath kde4_home_;
+  FilePath kde4_config_;
+  FilePath kioslaverc4_;
+};
+
+// Builds an identifier for each test in an array.
+#define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc)
+
+TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
+  std::vector<std::string> empty_ignores;
+
+  std::vector<std::string> google_ignores;
+  google_ignores.push_back("*.google.com");
+
+  // Inspired from proxy_config_service_win_unittest.cc.
+  // Very neat, but harder to track down failures though.
+  const struct {
+    // Short description to identify the test
+    std::string description;
+
+    // Input.
+    GConfValues values;
+
+    // Expected outputs (availability and fields of ProxyConfig).
+    ProxyConfigService::ConfigAvailability availability;
+    bool auto_detect;
+    GURL pac_url;
+    ProxyRulesExpectation proxy_rules;
+  } tests[] = {
+    {
+      TEST_DESC("No proxying"),
+      { // Input.
+        "none",                   // mode
+        "",                       // autoconfig_url
+        "", "", "", "",           // hosts
+        0, 0, 0, 0,               // ports
+        FALSE, FALSE, FALSE,      // use, same, auth
+        empty_ignores,            // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                      // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Auto detect"),
+      { // Input.
+        "auto",                   // mode
+        "",                       // autoconfig_url
+        "", "", "", "",           // hosts
+        0, 0, 0, 0,               // ports
+        FALSE, FALSE, FALSE,      // use, same, auth
+        empty_ignores,            // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Valid PAC URL"),
+      { // Input.
+        "auto",                      // mode
+        "http://wpad/wpad.dat",      // autoconfig_url
+        "", "", "", "",              // hosts
+        0, 0, 0, 0,                  // ports
+        FALSE, FALSE, FALSE,         // use, same, auth
+        empty_ignores,               // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                         // auto_detect
+      GURL("http://wpad/wpad.dat"),  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Invalid PAC URL"),
+      { // Input.
+        "auto",                      // mode
+        "wpad.dat",                  // autoconfig_url
+        "", "", "", "",              // hosts
+        0, 0, 0, 0,                  // ports
+        FALSE, FALSE, FALSE,         // use, same, auth
+        empty_ignores,               // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                          // auto_detect
+      GURL(),                        // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Single-host in proxy list"),
+      { // Input.
+        "manual",                              // mode
+        "",                                    // autoconfig_url
+        "www.google.com", "", "", "",          // hosts
+        80, 0, 0, 0,                           // ports
+        TRUE, TRUE, FALSE,                     // use, same, auth
+        empty_ignores,                         // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:80",  // single proxy
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("use_http_proxy is honored"),
+      { // Input.
+        "manual",                              // mode
+        "",                                    // autoconfig_url
+        "www.google.com", "", "", "",          // hosts
+        80, 0, 0, 0,                           // ports
+        FALSE, TRUE, FALSE,                    // use, same, auth
+        empty_ignores,                         // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("use_http_proxy and use_same_proxy are optional"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "www.google.com", "", "", "",                 // hosts
+        80, 0, 0, 0,                                  // ports
+        UNSET, UNSET, FALSE,                          // use, same, auth
+        empty_ignores,                                // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Single-host, different port"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "www.google.com", "", "", "",                 // hosts
+        88, 0, 0, 0,                                  // ports
+        TRUE, TRUE, FALSE,                            // use, same, auth
+        empty_ignores,                                // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:88",  // single proxy
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Per-scheme proxy rules"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "www.google.com",                             // http_host
+        "www.foo.com",                                // secure_host
+        "ftp.foo.com",                                // ftp
+        "",                                           // socks
+        88, 110, 121, 0,                              // ports
+        TRUE, FALSE, FALSE,                           // use, same, auth
+        empty_ignores,                                // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:88",  // http
+          "www.foo.com:110",    // https
+          "ftp.foo.com:121",    // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("socks"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "", "", "", "socks.com",                      // hosts
+        0, 0, 0, 99,                                  // ports
+        TRUE, FALSE, FALSE,                           // use, same, auth
+        empty_ignores,                                // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::Single(
+          "socks5://socks.com:99",  // single proxy
+          "")                       // bypass rules
+    },
+
+    {
+      TEST_DESC("Per-scheme proxy rules with fallback to SOCKS"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "www.google.com",                             // http_host
+        "www.foo.com",                                // secure_host
+        "ftp.foo.com",                                // ftp
+        "foobar.net",                                 // socks
+        88, 110, 121, 99,                             // ports
+        TRUE, FALSE, FALSE,                           // use, same, auth
+        empty_ignores,                                // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::PerSchemeWithSocks(
+          "www.google.com:88",      // http
+          "www.foo.com:110",        // https
+          "ftp.foo.com:121",        // ftp
+          "socks5://foobar.net:99", // socks
+          ""),                      // bypass rules
+    },
+
+    {
+      TEST_DESC("Per-scheme proxy rules (just HTTP) with fallback to SOCKS"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "www.google.com",                             // http_host
+        "",                                           // secure_host
+        "",                                           // ftp
+        "foobar.net",                                 // socks
+        88, 0, 0, 99,                                 // ports
+        TRUE, FALSE, FALSE,                           // use, same, auth
+        empty_ignores,                                // ignore_hosts
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::PerSchemeWithSocks(
+          "www.google.com:88",      // http
+          "",                       // https
+          "",                       // ftp
+          "socks5://foobar.net:99", // socks
+          ""),                      // bypass rules
+    },
+
+    {
+      TEST_DESC("Bypass *.google.com"),
+      { // Input.
+        "manual",                                     // mode
+        "",                                           // autoconfig_url
+        "www.google.com", "", "", "",                 // hosts
+        80, 0, 0, 0,                                  // ports
+        TRUE, TRUE, FALSE,                            // use, same, auth
+        google_ignores,                               // ignore_hosts
+      },
+
+      ProxyConfigService::CONFIG_VALID,
+      false,                                          // auto_detect
+      GURL(),                                         // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:80",   // single proxy
+          "*.google.com"),       // bypass rules
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
+                                    tests[i].description.c_str()));
+    MockEnvironment* env = new MockEnvironment;
+    MockSettingGetter* setting_getter = new MockSettingGetter;
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env, setting_getter));
+    ProxyConfig config;
+    setting_getter->values = tests[i].values;
+    sync_config_getter.SetupAndInitialFetch();
+    ProxyConfigService::ConfigAvailability availability =
+        sync_config_getter.SyncGetLatestProxyConfig(&config);
+    EXPECT_EQ(tests[i].availability, availability);
+
+    if (availability == ProxyConfigService::CONFIG_VALID) {
+      EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
+      EXPECT_EQ(tests[i].pac_url, config.pac_url());
+      EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+    }
+  }
+}
+
+TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
+  // Inspired from proxy_config_service_win_unittest.cc.
+  const struct {
+    // Short description to identify the test
+    std::string description;
+
+    // Input.
+    EnvVarValues values;
+
+    // Expected outputs (availability and fields of ProxyConfig).
+    ProxyConfigService::ConfigAvailability availability;
+    bool auto_detect;
+    GURL pac_url;
+    ProxyRulesExpectation proxy_rules;
+  } tests[] = {
+    {
+      TEST_DESC("No proxying"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        NULL,  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        "*",  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                      // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Auto detect"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        "",    // auto_proxy
+        NULL,  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Valid PAC URL"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        "http://wpad/wpad.dat",  // auto_proxy
+        NULL,  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                         // auto_detect
+      GURL("http://wpad/wpad.dat"),  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Invalid PAC URL"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        "wpad.dat",  // auto_proxy
+        NULL,  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Single-host in proxy list"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "www.google.com",  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:80",  // single proxy
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Single-host, different port"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "www.google.com:99",  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:99",  // single
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Tolerate a scheme"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "http://www.google.com:99",  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:99",  // single proxy
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Per-scheme proxy rules"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        NULL,  // all_proxy
+        "www.google.com:80", "www.foo.com:110", "ftp.foo.com:121",  // per-proto
+        NULL, NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "www.foo.com:110",    // https
+          "ftp.foo.com:121",    // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("socks"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "",  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        "socks.com:888", NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "socks5://socks.com:888",  // single proxy
+          ""),                       // bypass rules
+    },
+
+    {
+      TEST_DESC("socks4"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "",  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        "socks.com:888", "4",  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "socks4://socks.com:888",  // single proxy
+          ""),                       // bypass rules
+    },
+
+    {
+      TEST_DESC("socks default port"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "",  // all_proxy
+        NULL, NULL, NULL,  // per-proto proxies
+        "socks.com", NULL,  // SOCKS
+        NULL,  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "socks5://socks.com:1080",  // single proxy
+          ""),                        // bypass rules
+    },
+
+    {
+      TEST_DESC("bypass"),
+      { // Input.
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        "www.google.com",  // all_proxy
+        NULL, NULL, NULL,  // per-proto
+        NULL, NULL,  // SOCKS
+        ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8",  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                      // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:80",
+          "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8"),
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
+                                    tests[i].description.c_str()));
+    MockEnvironment* env = new MockEnvironment;
+    MockSettingGetter* setting_getter = new MockSettingGetter;
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env, setting_getter));
+    ProxyConfig config;
+    env->values = tests[i].values;
+    sync_config_getter.SetupAndInitialFetch();
+    ProxyConfigService::ConfigAvailability availability =
+        sync_config_getter.SyncGetLatestProxyConfig(&config);
+    EXPECT_EQ(tests[i].availability, availability);
+
+    if (availability == ProxyConfigService::CONFIG_VALID) {
+      EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
+      EXPECT_EQ(tests[i].pac_url, config.pac_url());
+      EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+    }
+  }
+}
+
+TEST_F(ProxyConfigServiceLinuxTest, GconfNotification) {
+  MockEnvironment* env = new MockEnvironment;
+  MockSettingGetter* setting_getter = new MockSettingGetter;
+  ProxyConfigServiceLinux* service =
+      new ProxyConfigServiceLinux(env, setting_getter);
+  SynchConfigGetter sync_config_getter(service);
+  ProxyConfig config;
+
+  // Start with no proxy.
+  setting_getter->values.mode = "none";
+  sync_config_getter.SetupAndInitialFetch();
+  EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+            sync_config_getter.SyncGetLatestProxyConfig(&config));
+  EXPECT_FALSE(config.auto_detect());
+
+  // Now set to auto-detect.
+  setting_getter->values.mode = "auto";
+  // Simulate setting change notification callback.
+  service->OnCheckProxyConfigSettings();
+  EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+            sync_config_getter.SyncGetLatestProxyConfig(&config));
+  EXPECT_TRUE(config.auto_detect());
+}
+
+TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
+  // One of the tests below needs a worst-case long line prefix. We build it
+  // programmatically so that it will always be the right size.
+  std::string long_line;
+  size_t limit = ProxyConfigServiceLinux::SettingGetter::BUFFER_SIZE - 1;
+  for (size_t i = 0; i < limit; ++i)
+    long_line += "-";
+
+  // Inspired from proxy_config_service_win_unittest.cc.
+  const struct {
+    // Short description to identify the test
+    std::string description;
+
+    // Input.
+    std::string kioslaverc;
+    EnvVarValues env_values;
+
+    // Expected outputs (availability and fields of ProxyConfig).
+    ProxyConfigService::ConfigAvailability availability;
+    bool auto_detect;
+    GURL pac_url;
+    ProxyRulesExpectation proxy_rules;
+  } tests[] = {
+    {
+      TEST_DESC("No proxying"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=0\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                      // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Auto detect"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=3\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Valid PAC URL"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=2\n"
+          "Proxy Config Script=http://wpad/wpad.dat\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                         // auto_detect
+      GURL("http://wpad/wpad.dat"),  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Valid PAC file without file://"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=2\n"
+          "Proxy Config Script=/wpad/wpad.dat\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                         // auto_detect
+      GURL("file:///wpad/wpad.dat"),  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Per-scheme proxy rules"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "httpsProxy=www.foo.com\nftpProxy=ftp.foo.com\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "www.foo.com:80",     // https
+          "ftp.foo.com:80",     // http
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Only HTTP proxy specified"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\n"
+          "httpProxy=www.google.com\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Only HTTP proxy specified, different port"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\n"
+          "httpProxy=www.google.com:88\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:88",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Only HTTP proxy specified, different port, space-delimited"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\n"
+          "httpProxy=www.google.com 88\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:88",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Bypass *.google.com"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "NoProxyFor=.google.com\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          "*.google.com"),      // bypass rules
+    },
+
+    {
+      TEST_DESC("Bypass *.google.com and *.kde.org"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "NoProxyFor=.google.com,.kde.org\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",           // http
+          "",                            // https
+          "",                            // ftp
+          "*.google.com,*.kde.org"),     // bypass rules
+    },
+
+    {
+      TEST_DESC("Correctly parse bypass list with ReversedException"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "NoProxyFor=.google.com\nReversedException=true\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerSchemeWithBypassReversed(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          "*.google.com"),      // bypass rules
+    },
+
+    {
+      TEST_DESC("socks"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nsocksProxy=socks.com 888\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "socks5://socks.com:888",  // single proxy
+          ""),                       // bypass rules
+    },
+
+    {
+      TEST_DESC("socks4"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nsocksProxy=socks4://socks.com 888\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "socks4://socks.com:888",  // single proxy
+          ""),                       // bypass rules
+    },
+
+    {
+      TEST_DESC("Treat all hostname patterns as wildcard patterns"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "NoProxyFor=google.com,kde.org,<local>\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",              // http
+          "",                               // https
+          "",                               // ftp
+          "*google.com,*kde.org,<local>"),  // bypass rules
+    },
+
+    {
+      TEST_DESC("Allow trailing whitespace after boolean value"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "NoProxyFor=.google.com\nReversedException=true  \n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerSchemeWithBypassReversed(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          "*.google.com"),      // bypass rules
+    },
+
+    {
+      TEST_DESC("Ignore settings outside [Proxy Settings]"),
+
+      // Input.
+      "httpsProxy=www.foo.com\n[Proxy Settings]\nProxyType=1\n"
+          "httpProxy=www.google.com\n[Other Section]\nftpProxy=ftp.foo.com\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Handle CRLF line endings"),
+
+      // Input.
+      "[Proxy Settings]\r\nProxyType=1\r\nhttpProxy=www.google.com\r\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Handle blank lines and mixed line endings"),
+
+      // Input.
+      "[Proxy Settings]\r\n\nProxyType=1\n\r\nhttpProxy=www.google.com\n\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Handle localized settings"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType[$e]=1\nhttpProxy[$e]=www.google.com\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "",                   // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Ignore malformed localized settings"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n"
+          "httpsProxy$e]=www.foo.com\nftpProxy=ftp.foo.com\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "ftp.foo.com:80",     // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Handle strange whitespace"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType [$e] =2\n"
+          "  Proxy Config Script =  http:// foo\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL("http:// foo"),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Ignore all of a line which is too long"),
+
+      // Input.
+      std::string("[Proxy Settings]\nProxyType=1\nftpProxy=ftp.foo.com\n") +
+          long_line + "httpsProxy=www.foo.com\nhttpProxy=www.google.com\n",
+      {},                                          // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                       // auto_detect
+      GURL(),                                      // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "",                   // https
+          "ftp.foo.com:80",     // ftp
+          ""),                  // bypass rules
+    },
+
+    {
+      TEST_DESC("Indirect Proxy - no env vars set"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n"
+          "httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n",
+      {},                                      // env_values
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    {
+      TEST_DESC("Indirect Proxy - with env vars set"),
+
+      // Input.
+      "[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n"
+          "httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n",
+      {  // env_values
+        NULL,  // DESKTOP_SESSION
+        NULL,  // HOME
+        NULL,  // KDEHOME
+        NULL,  // KDE_SESSION_VERSION
+        NULL,  // auto_proxy
+        NULL,  // all_proxy
+        "www.normal.com",  // http_proxy
+        "www.secure.com",  // https_proxy
+        "ftp.foo.com",  // ftp_proxy
+        NULL, NULL,  // SOCKS
+        ".google.com, .kde.org",  // no_proxy
+      },
+
+      // Expected result.
+      ProxyConfigService::CONFIG_VALID,
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.normal.com:80",           // http
+          "www.secure.com:80",           // https
+          "ftp.foo.com:80",              // ftp
+          "*.google.com,*.kde.org"),     // bypass rules
+    },
+
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
+                                    tests[i].description.c_str()));
+    MockEnvironment* env = new MockEnvironment;
+    env->values = tests[i].env_values;
+    // Force the KDE getter to be used and tell it where the test is.
+    env->values.DESKTOP_SESSION = "kde4";
+    env->values.KDEHOME = kde_home_.value().c_str();
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env));
+    ProxyConfig config;
+    // Overwrite the kioslaverc file.
+    file_util::WriteFile(kioslaverc_, tests[i].kioslaverc.c_str(),
+                         tests[i].kioslaverc.length());
+    sync_config_getter.SetupAndInitialFetch();
+    ProxyConfigService::ConfigAvailability availability =
+        sync_config_getter.SyncGetLatestProxyConfig(&config);
+    EXPECT_EQ(tests[i].availability, availability);
+
+    if (availability == ProxyConfigService::CONFIG_VALID) {
+      EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
+      EXPECT_EQ(tests[i].pac_url, config.pac_url());
+      EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+    }
+  }
+}
+
+TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) {
+  // Auto detect proxy settings.
+  std::string slaverc3 = "[Proxy Settings]\nProxyType=3\n";
+  // Valid PAC URL.
+  std::string slaverc4 = "[Proxy Settings]\nProxyType=2\n"
+                             "Proxy Config Script=http://wpad/wpad.dat\n";
+  GURL slaverc4_pac_url("http://wpad/wpad.dat");
+
+  // Overwrite the .kde kioslaverc file.
+  file_util::WriteFile(kioslaverc_, slaverc3.c_str(), slaverc3.length());
+
+  // If .kde4 exists it will mess up the first test. It should not, as
+  // we created the directory for $HOME in the test setup.
+  CHECK(!file_util::DirectoryExists(kde4_home_));
+
+  { SCOPED_TRACE("KDE4, no .kde4 directory, verify fallback");
+    MockEnvironment* env = new MockEnvironment;
+    env->values.DESKTOP_SESSION = "kde4";
+    env->values.HOME = user_home_.value().c_str();
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env));
+    ProxyConfig config;
+    sync_config_getter.SetupAndInitialFetch();
+    EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+              sync_config_getter.SyncGetLatestProxyConfig(&config));
+    EXPECT_TRUE(config.auto_detect());
+    EXPECT_EQ(GURL(), config.pac_url());
+  }
+
+  // Now create .kde4 and put a kioslaverc in the config directory.
+  // Note that its timestamp will be at least as new as the .kde one.
+  file_util::CreateDirectory(kde4_config_);
+  file_util::WriteFile(kioslaverc4_, slaverc4.c_str(), slaverc4.length());
+  CHECK(file_util::PathExists(kioslaverc4_));
+
+  { SCOPED_TRACE("KDE4, .kde4 directory present, use it");
+    MockEnvironment* env = new MockEnvironment;
+    env->values.DESKTOP_SESSION = "kde4";
+    env->values.HOME = user_home_.value().c_str();
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env));
+    ProxyConfig config;
+    sync_config_getter.SetupAndInitialFetch();
+    EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+              sync_config_getter.SyncGetLatestProxyConfig(&config));
+    EXPECT_FALSE(config.auto_detect());
+    EXPECT_EQ(slaverc4_pac_url, config.pac_url());
+  }
+
+  { SCOPED_TRACE("KDE3, .kde4 directory present, ignore it");
+    MockEnvironment* env = new MockEnvironment;
+    env->values.DESKTOP_SESSION = "kde";
+    env->values.HOME = user_home_.value().c_str();
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env));
+    ProxyConfig config;
+    sync_config_getter.SetupAndInitialFetch();
+    EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+              sync_config_getter.SyncGetLatestProxyConfig(&config));
+    EXPECT_TRUE(config.auto_detect());
+    EXPECT_EQ(GURL(), config.pac_url());
+  }
+
+  { SCOPED_TRACE("KDE4, .kde4 directory present, KDEHOME set to .kde");
+    MockEnvironment* env = new MockEnvironment;
+    env->values.DESKTOP_SESSION = "kde4";
+    env->values.HOME = user_home_.value().c_str();
+    env->values.KDEHOME = kde_home_.value().c_str();
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env));
+    ProxyConfig config;
+    sync_config_getter.SetupAndInitialFetch();
+    EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+              sync_config_getter.SyncGetLatestProxyConfig(&config));
+    EXPECT_TRUE(config.auto_detect());
+    EXPECT_EQ(GURL(), config.pac_url());
+  }
+
+  // Finally, make the .kde4 config directory older than the .kde directory
+  // and make sure we then use .kde instead of .kde4 since it's newer.
+  file_util::SetLastModifiedTime(kde4_config_, base::Time());
+
+  { SCOPED_TRACE("KDE4, very old .kde4 directory present, use .kde");
+    MockEnvironment* env = new MockEnvironment;
+    env->values.DESKTOP_SESSION = "kde4";
+    env->values.HOME = user_home_.value().c_str();
+    SynchConfigGetter sync_config_getter(
+        new ProxyConfigServiceLinux(env));
+    ProxyConfig config;
+    sync_config_getter.SetupAndInitialFetch();
+    EXPECT_EQ(ProxyConfigService::CONFIG_VALID,
+              sync_config_getter.SyncGetLatestProxyConfig(&config));
+    EXPECT_TRUE(config.auto_detect());
+    EXPECT_EQ(GURL(), config.pac_url());
+  }
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_mac.cc b/src/net/proxy/proxy_config_service_mac.cc
new file mode 100644
index 0000000..f7c8ce7
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_mac.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/proxy_config_service_mac.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/message_loop.h"
+#include "base/sys_string_conversions.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_server.h"
+
+namespace net {
+
+namespace {
+
+// Utility function to pull out a boolean value from a dictionary and return it,
+// returning a default value if the key is not present.
+bool GetBoolFromDictionary(CFDictionaryRef dict,
+                           CFStringRef key,
+                           bool default_value) {
+  CFNumberRef number = base::mac::GetValueFromDictionary<CFNumberRef>(dict,
+                                                                      key);
+  if (!number)
+    return default_value;
+
+  int int_value;
+  if (CFNumberGetValue(number, kCFNumberIntType, &int_value))
+    return int_value;
+  else
+    return default_value;
+}
+
+void GetCurrentProxyConfig(ProxyConfig* config) {
+  base::mac::ScopedCFTypeRef<CFDictionaryRef> config_dict(
+      SCDynamicStoreCopyProxies(NULL));
+  DCHECK(config_dict);
+
+  // auto-detect
+
+  // There appears to be no UI for this configuration option, and we're not sure
+  // if Apple's proxy code even takes it into account. But the constant is in
+  // the header file so we'll use it.
+  config->set_auto_detect(
+      GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesProxyAutoDiscoveryEnable,
+                            false));
+
+  // PAC file
+
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesProxyAutoConfigEnable,
+                            false)) {
+    CFStringRef pac_url_ref = base::mac::GetValueFromDictionary<CFStringRef>(
+        config_dict.get(), kSCPropNetProxiesProxyAutoConfigURLString);
+    if (pac_url_ref)
+      config->set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
+  }
+
+  // proxies (for now ftp, http, https, and SOCKS)
+
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesFTPEnable,
+                            false)) {
+    ProxyServer proxy_server =
+        ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
+                                    config_dict.get(),
+                                    kSCPropNetProxiesFTPProxy,
+                                    kSCPropNetProxiesFTPPort);
+    if (proxy_server.is_valid()) {
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+      config->proxy_rules().proxy_for_ftp = proxy_server;
+    }
+  }
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesHTTPEnable,
+                            false)) {
+    ProxyServer proxy_server =
+        ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
+                                    config_dict.get(),
+                                    kSCPropNetProxiesHTTPProxy,
+                                    kSCPropNetProxiesHTTPPort);
+    if (proxy_server.is_valid()) {
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+      config->proxy_rules().proxy_for_http = proxy_server;
+    }
+  }
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesHTTPSEnable,
+                            false)) {
+    ProxyServer proxy_server =
+        ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
+                                    config_dict.get(),
+                                    kSCPropNetProxiesHTTPSProxy,
+                                    kSCPropNetProxiesHTTPSPort);
+    if (proxy_server.is_valid()) {
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+      config->proxy_rules().proxy_for_https = proxy_server;
+    }
+  }
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesSOCKSEnable,
+                            false)) {
+    ProxyServer proxy_server =
+        ProxyServer::FromDictionary(ProxyServer::SCHEME_SOCKS5,
+                                    config_dict.get(),
+                                    kSCPropNetProxiesSOCKSProxy,
+                                    kSCPropNetProxiesSOCKSPort);
+    if (proxy_server.is_valid()) {
+      config->proxy_rules().type =
+          ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
+      config->proxy_rules().fallback_proxy = proxy_server;
+    }
+  }
+
+  // proxy bypass list
+
+  CFArrayRef bypass_array_ref = base::mac::GetValueFromDictionary<CFArrayRef>(
+      config_dict.get(), kSCPropNetProxiesExceptionsList);
+  if (bypass_array_ref) {
+    CFIndex bypass_array_count = CFArrayGetCount(bypass_array_ref);
+    for (CFIndex i = 0; i < bypass_array_count; ++i) {
+      CFStringRef bypass_item_ref = base::mac::CFCast<CFStringRef>(
+          CFArrayGetValueAtIndex(bypass_array_ref, i));
+      if (!bypass_item_ref) {
+        LOG(WARNING) << "Expected value for item " << i
+                     << " in the kSCPropNetProxiesExceptionsList"
+                        " to be a CFStringRef but it was not";
+
+      } else {
+        config->proxy_rules().bypass_rules.AddRuleFromString(
+            base::SysCFStringRefToUTF8(bypass_item_ref));
+      }
+    }
+  }
+
+  // proxy bypass boolean
+
+  if (GetBoolFromDictionary(config_dict.get(),
+                            kSCPropNetProxiesExcludeSimpleHostnames,
+                            false)) {
+    config->proxy_rules().bypass_rules.AddRuleToBypassLocal();
+  }
+
+  // Source
+  config->set_source(PROXY_CONFIG_SOURCE_SYSTEM);
+}
+
+}  // namespace
+
+// Reference-counted helper for posting a task to
+// ProxyConfigServiceMac::OnProxyConfigChanged between the notifier and IO
+// thread. This helper object may outlive the ProxyConfigServiceMac.
+class ProxyConfigServiceMac::Helper
+    : public base::RefCountedThreadSafe<ProxyConfigServiceMac::Helper> {
+ public:
+  explicit Helper(ProxyConfigServiceMac* parent) : parent_(parent) {
+    DCHECK(parent);
+  }
+
+  // Called when the parent is destroyed.
+  void Orphan() {
+    parent_ = NULL;
+  }
+
+  void OnProxyConfigChanged(const ProxyConfig& new_config) {
+    if (parent_)
+      parent_->OnProxyConfigChanged(new_config);
+  }
+
+ private:
+  friend class base::RefCountedThreadSafe<Helper>;
+  ~Helper() {}
+
+  ProxyConfigServiceMac* parent_;
+};
+
+void ProxyConfigServiceMac::Forwarder::SetDynamicStoreNotificationKeys(
+    SCDynamicStoreRef store) {
+  proxy_config_service_->SetDynamicStoreNotificationKeys(store);
+}
+
+void ProxyConfigServiceMac::Forwarder::OnNetworkConfigChange(
+    CFArrayRef changed_keys) {
+  proxy_config_service_->OnNetworkConfigChange(changed_keys);
+}
+
+ProxyConfigServiceMac::ProxyConfigServiceMac(
+    base::SingleThreadTaskRunner* io_thread_task_runner)
+    : forwarder_(this),
+      has_fetched_config_(false),
+      helper_(new Helper(this)),
+      io_thread_task_runner_(io_thread_task_runner) {
+  DCHECK(io_thread_task_runner_);
+  config_watcher_.reset(new NetworkConfigWatcherMac(&forwarder_));
+}
+
+ProxyConfigServiceMac::~ProxyConfigServiceMac() {
+  DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
+  // Delete the config_watcher_ to ensure the notifier thread finishes before
+  // this object is destroyed.
+  config_watcher_.reset();
+  helper_->Orphan();
+}
+
+void ProxyConfigServiceMac::AddObserver(Observer* observer) {
+  DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
+  observers_.AddObserver(observer);
+}
+
+void ProxyConfigServiceMac::RemoveObserver(Observer* observer) {
+  DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
+  observers_.RemoveObserver(observer);
+}
+
+net::ProxyConfigService::ConfigAvailability
+    ProxyConfigServiceMac::GetLatestProxyConfig(ProxyConfig* config) {
+  DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
+
+  // Lazy-initialize by fetching the proxy setting from this thread.
+  if (!has_fetched_config_) {
+    GetCurrentProxyConfig(&last_config_fetched_);
+    has_fetched_config_ = true;
+  }
+
+  *config = last_config_fetched_;
+  return has_fetched_config_ ? CONFIG_VALID : CONFIG_PENDING;
+}
+
+void ProxyConfigServiceMac::SetDynamicStoreNotificationKeys(
+    SCDynamicStoreRef store) {
+  // Called on notifier thread.
+
+  CFStringRef proxies_key = SCDynamicStoreKeyCreateProxies(NULL);
+  CFArrayRef key_array = CFArrayCreate(
+      NULL, (const void **)(&proxies_key), 1, &kCFTypeArrayCallBacks);
+
+  bool ret = SCDynamicStoreSetNotificationKeys(store, key_array, NULL);
+  // TODO(willchan): Figure out a proper way to handle this rather than crash.
+  CHECK(ret);
+
+  CFRelease(key_array);
+  CFRelease(proxies_key);
+}
+
+void ProxyConfigServiceMac::OnNetworkConfigChange(CFArrayRef changed_keys) {
+  // Called on notifier thread.
+
+  // Fetch the new system proxy configuration.
+  ProxyConfig new_config;
+  GetCurrentProxyConfig(&new_config);
+
+  // Call OnProxyConfigChanged() on the IO thread to notify our observers.
+  io_thread_task_runner_->PostTask(
+      FROM_HERE,
+      base::Bind(&Helper::OnProxyConfigChanged, helper_.get(), new_config));
+}
+
+void ProxyConfigServiceMac::OnProxyConfigChanged(
+    const ProxyConfig& new_config) {
+  DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
+
+  // Keep track of the last value we have seen.
+  has_fetched_config_ = true;
+  last_config_fetched_ = new_config;
+
+  // Notify all the observers.
+  FOR_EACH_OBSERVER(Observer, observers_,
+                    OnProxyConfigChanged(new_config, CONFIG_VALID));
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_mac.h b/src/net/proxy/proxy_config_service_mac.h
new file mode 100644
index 0000000..cf513a0
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_mac.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_MAC_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_MAC_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "net/base/network_config_watcher_mac.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace net {
+
+// TODO(sergeyu): This class needs to be exported because remoting code
+// creates it directly. Fix that and remove NET_EXPORT here.
+// crbug.com/125104
+class NET_EXPORT ProxyConfigServiceMac : public ProxyConfigService {
+ public:
+  // Constructs a ProxyConfigService that watches the Mac OS system settings.
+  // This instance is expected to be operated and deleted on the same thread
+  // (however it may be constructed from a different thread).
+  explicit ProxyConfigServiceMac(
+      base::SingleThreadTaskRunner* io_thread_task_runner);
+  virtual ~ProxyConfigServiceMac();
+
+ public:
+  // ProxyConfigService implementation:
+  virtual void AddObserver(Observer* observer) OVERRIDE;
+  virtual void RemoveObserver(Observer* observer) OVERRIDE;
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) OVERRIDE;
+
+ private:
+  class Helper;
+
+  // Forwarder just exists to keep the NetworkConfigWatcherMac API out of
+  // ProxyConfigServiceMac's public API.
+  class Forwarder : public NetworkConfigWatcherMac::Delegate {
+   public:
+    explicit Forwarder(ProxyConfigServiceMac* proxy_config_service)
+        : proxy_config_service_(proxy_config_service) {}
+
+    // NetworkConfigWatcherMac::Delegate implementation:
+    virtual void StartReachabilityNotifications() OVERRIDE {}
+    virtual void SetDynamicStoreNotificationKeys(
+        SCDynamicStoreRef store) OVERRIDE;
+    virtual void OnNetworkConfigChange(CFArrayRef changed_keys) OVERRIDE;
+
+   private:
+    ProxyConfigServiceMac* const proxy_config_service_;
+    DISALLOW_COPY_AND_ASSIGN(Forwarder);
+  };
+
+  // Methods directly called by the NetworkConfigWatcherMac::Delegate:
+  void SetDynamicStoreNotificationKeys(SCDynamicStoreRef store);
+  void OnNetworkConfigChange(CFArrayRef changed_keys);
+
+  // Called when the proxy configuration has changed, to notify the observers.
+  void OnProxyConfigChanged(const ProxyConfig& new_config);
+
+  Forwarder forwarder_;
+  scoped_ptr<const NetworkConfigWatcherMac> config_watcher_;
+
+  ObserverList<Observer> observers_;
+
+  // Holds the last system proxy settings that we fetched.
+  bool has_fetched_config_;
+  ProxyConfig last_config_fetched_;
+
+  scoped_refptr<Helper> helper_;
+
+  // The thread that we expect to be operated on.
+  const scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceMac);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_MAC_H_
diff --git a/src/net/proxy/proxy_config_service_win.cc b/src/net/proxy/proxy_config_service_win.cc
new file mode 100644
index 0000000..60f6f74
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_win.cc
@@ -0,0 +1,194 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_config_service_win.h"
+
+#include <windows.h>
+#include <winhttp.h>
+
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "base/stl_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "base/win/registry.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
+
+#pragma comment(lib, "winhttp.lib")
+
+namespace net {
+
+namespace {
+
+const int kPollIntervalSec = 10;
+
+void FreeIEConfig(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* ie_config) {
+  if (ie_config->lpszAutoConfigUrl)
+    GlobalFree(ie_config->lpszAutoConfigUrl);
+  if (ie_config->lpszProxy)
+    GlobalFree(ie_config->lpszProxy);
+  if (ie_config->lpszProxyBypass)
+    GlobalFree(ie_config->lpszProxyBypass);
+}
+
+}  // namespace
+
+// RegKey and ObjectWatcher pair.
+class ProxyConfigServiceWin::KeyEntry {
+ public:
+  bool StartWatching(base::win::ObjectWatcher::Delegate* delegate) {
+    // Try to create a watch event for the registry key (which watches the
+    // sibling tree as well).
+    if (key_.StartWatching() != ERROR_SUCCESS)
+      return false;
+
+    // Now setup an ObjectWatcher for this event, so we get OnObjectSignaled()
+    // invoked on this message loop once it is signalled.
+    if (!watcher_.StartWatching(key_.watch_event(), delegate))
+      return false;
+
+    return true;
+  }
+
+  bool CreateRegKey(HKEY rootkey, const wchar_t* subkey) {
+    return key_.Create(rootkey, subkey, KEY_NOTIFY) == ERROR_SUCCESS;
+  }
+
+  HANDLE watch_event() const {
+    return key_.watch_event();
+  }
+
+ private:
+  base::win::RegKey key_;
+  base::win::ObjectWatcher watcher_;
+};
+
+ProxyConfigServiceWin::ProxyConfigServiceWin()
+    : PollingProxyConfigService(
+          base::TimeDelta::FromSeconds(kPollIntervalSec),
+          &ProxyConfigServiceWin::GetCurrentProxyConfig) {
+}
+
+ProxyConfigServiceWin::~ProxyConfigServiceWin() {
+  // The registry functions below will end up going to disk.  Do this on another
+  // thread to avoid slowing the IO thread.  http://crbug.com/61453
+  base::ThreadRestrictions::ScopedAllowIO allow_io;
+  STLDeleteElements(&keys_to_watch_);
+}
+
+void ProxyConfigServiceWin::AddObserver(Observer* observer) {
+  // Lazily-initialize our registry watcher.
+  StartWatchingRegistryForChanges();
+
+  // Let the super-class do its work now.
+  PollingProxyConfigService::AddObserver(observer);
+}
+
+void ProxyConfigServiceWin::StartWatchingRegistryForChanges() {
+  if (!keys_to_watch_.empty())
+    return;  // Already initialized.
+
+  // The registry functions below will end up going to disk.  Do this on another
+  // thread to avoid slowing the IO thread.  http://crbug.com/61453
+  base::ThreadRestrictions::ScopedAllowIO allow_io;
+
+  // There are a number of different places where proxy settings can live
+  // in the registry. In some cases it appears in a binary value, in other
+  // cases string values. Furthermore winhttp and wininet appear to have
+  // separate stores, and proxy settings can be configured per-machine
+  // or per-user.
+  //
+  // This function is probably not exhaustive in the registry locations it
+  // watches for changes, however it should catch the majority of the
+  // cases. In case we have missed some less common triggers (likely), we
+  // will catch them during the periodic (10 second) polling, so things
+  // will recover.
+
+  AddKeyToWatchList(
+      HKEY_CURRENT_USER,
+      L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
+
+  AddKeyToWatchList(
+      HKEY_LOCAL_MACHINE,
+      L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
+
+  AddKeyToWatchList(
+      HKEY_LOCAL_MACHINE,
+      L"SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\"
+      L"Internet Settings");
+}
+
+bool ProxyConfigServiceWin::AddKeyToWatchList(HKEY rootkey,
+                                              const wchar_t* subkey) {
+  scoped_ptr<KeyEntry> entry(new KeyEntry);
+  if (!entry->CreateRegKey(rootkey, subkey))
+    return false;
+
+  if (!entry->StartWatching(this))
+    return false;
+
+  keys_to_watch_.push_back(entry.release());
+  return true;
+}
+
+void ProxyConfigServiceWin::OnObjectSignaled(HANDLE object) {
+  // Figure out which registry key signalled this change.
+  KeyEntryList::iterator it;
+  for (it = keys_to_watch_.begin(); it != keys_to_watch_.end(); ++it) {
+    if ((*it)->watch_event() == object)
+      break;
+  }
+
+  DCHECK(it != keys_to_watch_.end());
+
+  // Keep watching the registry key.
+  if (!(*it)->StartWatching(this))
+    keys_to_watch_.erase(it);
+
+  // Have the PollingProxyConfigService test for changes.
+  CheckForChangesNow();
+}
+
+// static
+void ProxyConfigServiceWin::GetCurrentProxyConfig(ProxyConfig* config) {
+  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
+  if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)) {
+    LOG(ERROR) << "WinHttpGetIEProxyConfigForCurrentUser failed: " <<
+        GetLastError();
+    *config = ProxyConfig::CreateDirect();
+    config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED);
+    return;
+  }
+  SetFromIEConfig(config, ie_config);
+  FreeIEConfig(&ie_config);
+}
+
+// static
+void ProxyConfigServiceWin::SetFromIEConfig(
+    ProxyConfig* config,
+    const WINHTTP_CURRENT_USER_IE_PROXY_CONFIG& ie_config) {
+  if (ie_config.fAutoDetect)
+    config->set_auto_detect(true);
+  if (ie_config.lpszProxy) {
+    // lpszProxy may be a single proxy, or a proxy per scheme. The format
+    // is compatible with ProxyConfig::ProxyRules's string format.
+    config->proxy_rules().ParseFromString(WideToASCII(ie_config.lpszProxy));
+  }
+  if (ie_config.lpszProxyBypass) {
+    std::string proxy_bypass = WideToASCII(ie_config.lpszProxyBypass);
+
+    StringTokenizer proxy_server_bypass_list(proxy_bypass, ";, \t\n\r");
+    while (proxy_server_bypass_list.GetNext()) {
+      std::string bypass_url_domain = proxy_server_bypass_list.token();
+      config->proxy_rules().bypass_rules.AddRuleFromString(bypass_url_domain);
+    }
+  }
+  if (ie_config.lpszAutoConfigUrl)
+    config->set_pac_url(GURL(ie_config.lpszAutoConfigUrl));
+  config->set_source(PROXY_CONFIG_SOURCE_SYSTEM);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_service_win.h b/src/net/proxy/proxy_config_service_win.h
new file mode 100644
index 0000000..aa91b68
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_win.h
@@ -0,0 +1,80 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SERVICE_WIN_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_WIN_H_
+
+#include <windows.h>
+#include <winhttp.h>
+
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/gtest_prod_util.h"
+#include "base/win/object_watcher.h"
+#include "net/proxy/polling_proxy_config_service.h"
+
+namespace net {
+
+// Implementation of ProxyConfigService that retrieves the system proxy
+// settings.
+//
+// It works by calling WinHttpGetIEProxyConfigForCurrentUser() to fetch the
+// Internet Explorer proxy settings.
+//
+// We use two different strategies to notice when the configuration has
+// changed:
+//
+// (1) Watch the internet explorer settings registry keys for changes. When
+//     one of the registry keys pertaining to proxy settings has changed, we
+//     call WinHttpGetIEProxyConfigForCurrentUser() again to read the
+//     configuration's new value.
+//
+// (2) Do regular polling every 10 seconds during network activity to see if
+//     WinHttpGetIEProxyConfigForCurrentUser() returns something different.
+//
+// Ideally strategy (1) should be sufficient to pick up all of the changes.
+// However we still do the regular polling as a precaution in case the
+// implementation details of  WinHttpGetIEProxyConfigForCurrentUser() ever
+// change, or in case we got it wrong (and are not checking all possible
+// registry dependencies).
+class NET_EXPORT_PRIVATE ProxyConfigServiceWin
+    : public PollingProxyConfigService,
+      public base::win::ObjectWatcher::Delegate {
+ public:
+  ProxyConfigServiceWin();
+  virtual ~ProxyConfigServiceWin();
+
+  // Overrides a function from PollingProxyConfigService.
+  virtual void AddObserver(Observer* observer) OVERRIDE;
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(ProxyConfigServiceWinTest, SetFromIEConfig);
+  class KeyEntry;
+  typedef std::vector<KeyEntry*> KeyEntryList;
+
+  // Registers change observers on the registry keys relating to proxy settings.
+  void StartWatchingRegistryForChanges();
+
+  // Creates a new KeyEntry and appends it to |keys_to_watch_|. If the key
+  // fails to be created, it is not appended to the list and we return false.
+  bool AddKeyToWatchList(HKEY rootkey, const wchar_t* subkey);
+
+  // ObjectWatcher::Delegate methods:
+  // This is called whenever one of the registry keys we are watching change.
+  virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
+
+  static void GetCurrentProxyConfig(ProxyConfig* config);
+
+  // Set |config| using the proxy configuration values of |ie_config|.
+  static void SetFromIEConfig(
+      ProxyConfig* config,
+      const WINHTTP_CURRENT_USER_IE_PROXY_CONFIG& ie_config);
+
+  KeyEntryList keys_to_watch_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SERVICE_WIN_H_
diff --git a/src/net/proxy/proxy_config_service_win_unittest.cc b/src/net/proxy/proxy_config_service_win_unittest.cc
new file mode 100644
index 0000000..911949d
--- /dev/null
+++ b/src/net/proxy/proxy_config_service_win_unittest.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_config_service_win.h"
+
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
+  const struct {
+    // Input.
+    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config;
+
+    // Expected outputs (fields of the ProxyConfig).
+    bool auto_detect;
+    GURL pac_url;
+    ProxyRulesExpectation proxy_rules;
+    const char* proxy_bypass_list;  // newline separated
+  } tests[] = {
+    // Auto detect.
+    {
+      { // Input.
+        TRUE,  // fAutoDetect
+        NULL,  // lpszAutoConfigUrl
+        NULL,  // lpszProxy
+        NULL,  // lpszProxyBypass
+      },
+
+      // Expected result.
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    // Valid PAC url
+    {
+      { // Input.
+        FALSE,                    // fAutoDetect
+        L"http://wpad/wpad.dat",  // lpszAutoConfigUrl
+        NULL,                     // lpszProxy
+        NULL,                     // lpszProxy_bypass
+      },
+
+      // Expected result.
+      false,                         // auto_detect
+      GURL("http://wpad/wpad.dat"),  // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    // Invalid PAC url string.
+    {
+      { // Input.
+        FALSE,        // fAutoDetect
+        L"wpad.dat",  // lpszAutoConfigUrl
+        NULL,         // lpszProxy
+        NULL,         // lpszProxy_bypass
+      },
+
+      // Expected result.
+      false,                      // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::Empty(),
+    },
+
+    // Single-host in proxy list.
+    {
+      { // Input.
+        FALSE,              // fAutoDetect
+        NULL,               // lpszAutoConfigUrl
+        L"www.google.com",  // lpszProxy
+        NULL,               // lpszProxy_bypass
+      },
+
+      // Expected result.
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::Single(
+          "www.google.com:80",  // single proxy
+          ""),                  // bypass rules
+    },
+
+    // Per-scheme proxy rules.
+    {
+      { // Input.
+        FALSE,                                            // fAutoDetect
+        NULL,                                             // lpszAutoConfigUrl
+        L"http=www.google.com:80;https=www.foo.com:110",  // lpszProxy
+        NULL,                                             // lpszProxy_bypass
+      },
+
+      // Expected result.
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerScheme(
+          "www.google.com:80",  // http
+          "www.foo.com:110",   // https
+          "",                  // ftp
+          ""),                 // bypass rules
+    },
+
+    // SOCKS proxy configuration.
+    {
+      { // Input.
+        FALSE,                                            // fAutoDetect
+        NULL,                                             // lpszAutoConfigUrl
+        L"http=www.google.com:80;https=www.foo.com:110;"
+        L"ftp=ftpproxy:20;socks=foopy:130",               // lpszProxy
+        NULL,                                             // lpszProxy_bypass
+      },
+
+      // Expected result.
+      // Note that "socks" is interprted as meaning "socks4", since that is how
+      // Internet Explorer applies the settings. For more details on this
+      // policy, see:
+      // http://code.google.com/p/chromium/issues/detail?id=55912#c2
+      false,                                   // auto_detect
+      GURL(),                                  // pac_url
+      ProxyRulesExpectation::PerSchemeWithSocks(
+          "www.google.com:80",   // http
+          "www.foo.com:110",     // https
+          "ftpproxy:20",         // ftp
+          "socks4://foopy:130",  // socks
+          ""),                   // bypass rules
+    },
+
+    // Bypass local names.
+    {
+      { // Input.
+        TRUE,            // fAutoDetect
+        NULL,            // lpszAutoConfigUrl
+        NULL,            // lpszProxy
+        L"<local>",      // lpszProxy_bypass
+      },
+
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::EmptyWithBypass("<local>"),
+    },
+
+    // Bypass "google.com" and local names, using semicolon as delimiter
+    // (ignoring white space).
+    {
+      { // Input.
+        TRUE,                         // fAutoDetect
+        NULL,                         // lpszAutoConfigUrl
+        NULL,                         // lpszProxy
+        L"<local> ; google.com",      // lpszProxy_bypass
+      },
+
+      // Expected result.
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::EmptyWithBypass("<local>,google.com"),
+    },
+
+    // Bypass "foo.com" and "google.com", using lines as delimiter.
+    {
+      { // Input.
+        TRUE,                      // fAutoDetect
+        NULL,                      // lpszAutoConfigUrl
+        NULL,                      // lpszProxy
+        L"foo.com\r\ngoogle.com",  // lpszProxy_bypass
+      },
+
+      // Expected result.
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::EmptyWithBypass("foo.com,google.com"),
+    },
+
+    // Bypass "foo.com" and "google.com", using commas as delimiter.
+    {
+      { // Input.
+        TRUE,                      // fAutoDetect
+        NULL,                      // lpszAutoConfigUrl
+        NULL,                      // lpszProxy
+        L"foo.com, google.com",    // lpszProxy_bypass
+      },
+
+      // Expected result.
+      true,                       // auto_detect
+      GURL(),                     // pac_url
+      ProxyRulesExpectation::EmptyWithBypass("foo.com,google.com"),
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    ProxyConfig config;
+    ProxyConfigServiceWin::SetFromIEConfig(&config, tests[i].ie_config);
+
+    EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
+    EXPECT_EQ(tests[i].pac_url, config.pac_url());
+    EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
+    EXPECT_EQ(PROXY_CONFIG_SOURCE_SYSTEM, config.source());
+  }
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_source.cc b/src/net/proxy/proxy_config_source.cc
new file mode 100644
index 0000000..5695b9b
--- /dev/null
+++ b/src/net/proxy/proxy_config_source.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/proxy_config_source.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+namespace net {
+
+namespace {
+
+const char* kSourceNames[] = {
+  "UNKNOWN",
+  "SYSTEM",
+  "SYSTEM FAILED",
+  "GCONF",
+  "GSETTINGS",
+  "KDE",
+  "ENV",
+  "CUSTOM",
+  "TEST"
+};
+COMPILE_ASSERT(ARRAYSIZE_UNSAFE(kSourceNames) == NUM_PROXY_CONFIG_SOURCES,
+               source_names_incorrect_size);
+
+}  // namespace
+
+const char* ProxyConfigSourceToString(ProxyConfigSource source) {
+  DCHECK_GT(NUM_PROXY_CONFIG_SOURCES, source);
+  return kSourceNames[source];
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_config_source.h b/src/net/proxy/proxy_config_source.h
new file mode 100644
index 0000000..a7e375a
--- /dev/null
+++ b/src/net/proxy/proxy_config_source.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_CONFIG_SOURCE_H_
+#define NET_PROXY_PROXY_CONFIG_SOURCE_H_
+
+namespace net {
+
+// Source of the configuration settings encapsulated in a ProxyConfig object.
+
+// The source information is used for determining how credentials are used and
+// for logging.  When adding new values, remember to add a string to
+// kSourceNames[] in proxy_config_source.cc.
+enum ProxyConfigSource {
+  PROXY_CONFIG_SOURCE_UNKNOWN,       // The source hasn't been set.
+  PROXY_CONFIG_SOURCE_SYSTEM,        // System settings (Win/Mac).
+  PROXY_CONFIG_SOURCE_SYSTEM_FAILED, // Default settings after failure to
+                                     // determine system settings.
+  PROXY_CONFIG_SOURCE_GCONF,         // GConf (Linux)
+  PROXY_CONFIG_SOURCE_GSETTINGS,     // GSettings (Linux).
+  PROXY_CONFIG_SOURCE_KDE,           // KDE (Linux).
+  PROXY_CONFIG_SOURCE_ENV,           // Environment variables.
+  PROXY_CONFIG_SOURCE_CUSTOM,        // Custom settings local to the
+                                     // application (command line,
+                                     // extensions, application
+                                     // specific preferences, etc.)
+  PROXY_CONFIG_SOURCE_TEST,          // Test settings.
+  NUM_PROXY_CONFIG_SOURCES
+};
+
+// Returns a textual representation of the source.
+const char* ProxyConfigSourceToString(ProxyConfigSource source);
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_CONFIG_SOURCE_H_
diff --git a/src/net/proxy/proxy_config_unittest.cc b/src/net/proxy/proxy_config_unittest.cc
new file mode 100644
index 0000000..47ea689
--- /dev/null
+++ b/src/net/proxy/proxy_config_unittest.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
+#include "net/proxy/proxy_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+void ExpectProxyServerEquals(const char* expectation,
+                             const ProxyServer& proxy_server) {
+  if (expectation == NULL) {
+    EXPECT_FALSE(proxy_server.is_valid());
+  } else {
+    EXPECT_EQ(expectation, proxy_server.ToURI());
+  }
+}
+
+TEST(ProxyConfigTest, Equals) {
+  // Test |ProxyConfig::auto_detect|.
+
+  ProxyConfig config1;
+  config1.set_auto_detect(true);
+
+  ProxyConfig config2;
+  config2.set_auto_detect(false);
+
+  EXPECT_FALSE(config1.Equals(config2));
+  EXPECT_FALSE(config2.Equals(config1));
+
+  config2.set_auto_detect(true);
+
+  EXPECT_TRUE(config1.Equals(config2));
+  EXPECT_TRUE(config2.Equals(config1));
+
+  // Test |ProxyConfig::pac_url|.
+
+  config2.set_pac_url(GURL("http://wpad/wpad.dat"));
+
+  EXPECT_FALSE(config1.Equals(config2));
+  EXPECT_FALSE(config2.Equals(config1));
+
+  config1.set_pac_url(GURL("http://wpad/wpad.dat"));
+
+  EXPECT_TRUE(config1.Equals(config2));
+  EXPECT_TRUE(config2.Equals(config1));
+
+  // Test |ProxyConfig::proxy_rules|.
+
+  config2.proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+  config2.proxy_rules().single_proxy =
+      ProxyServer::FromURI("myproxy:80", ProxyServer::SCHEME_HTTP);
+
+  EXPECT_FALSE(config1.Equals(config2));
+  EXPECT_FALSE(config2.Equals(config1));
+
+  config1.proxy_rules().type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
+  config1.proxy_rules().single_proxy =
+      ProxyServer::FromURI("myproxy:100", ProxyServer::SCHEME_HTTP);
+
+  EXPECT_FALSE(config1.Equals(config2));
+  EXPECT_FALSE(config2.Equals(config1));
+
+  config1.proxy_rules().single_proxy =
+      ProxyServer::FromURI("myproxy", ProxyServer::SCHEME_HTTP);
+
+  EXPECT_TRUE(config1.Equals(config2));
+  EXPECT_TRUE(config2.Equals(config1));
+
+  // Test |ProxyConfig::bypass_rules|.
+
+  config2.proxy_rules().bypass_rules.AddRuleFromString("*.google.com");
+
+  EXPECT_FALSE(config1.Equals(config2));
+  EXPECT_FALSE(config2.Equals(config1));
+
+  config1.proxy_rules().bypass_rules.AddRuleFromString("*.google.com");
+
+  EXPECT_TRUE(config1.Equals(config2));
+  EXPECT_TRUE(config2.Equals(config1));
+
+  // Test |ProxyConfig::proxy_rules.reverse_bypass|.
+
+  config2.proxy_rules().reverse_bypass = true;
+
+  EXPECT_FALSE(config1.Equals(config2));
+  EXPECT_FALSE(config2.Equals(config1));
+
+  config1.proxy_rules().reverse_bypass = true;
+
+  EXPECT_TRUE(config1.Equals(config2));
+  EXPECT_TRUE(config2.Equals(config1));
+}
+
+TEST(ProxyConfigTest, ParseProxyRules) {
+  const struct {
+    const char* proxy_rules;
+
+    ProxyConfig::ProxyRules::Type type;
+    const char* single_proxy;
+    const char* proxy_for_http;
+    const char* proxy_for_https;
+    const char* proxy_for_ftp;
+    const char* fallback_proxy;
+  } tests[] = {
+    // One HTTP proxy for all schemes.
+    {
+      "myproxy:80",
+
+      ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY,
+      "myproxy:80",
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+    },
+
+    // Only specify a proxy server for "http://" urls.
+    {
+      "http=myproxy:80",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      "myproxy:80",
+      NULL,
+      NULL,
+      NULL,
+    },
+
+    // Specify an HTTP proxy for "ftp://" and a SOCKS proxy for "https://" urls.
+    {
+      "ftp=ftp-proxy ; https=socks4://foopy",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      NULL,
+      "socks4://foopy:1080",
+      "ftp-proxy:80",
+      NULL,
+    },
+
+    // Give a scheme-specific proxy as well as a non-scheme specific.
+    // The first entry "foopy" takes precedance marking this list as
+    // TYPE_SINGLE_PROXY.
+    {
+      "foopy ; ftp=ftp-proxy",
+
+      ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY,
+      "foopy:80",
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+    },
+
+    // Give a scheme-specific proxy as well as a non-scheme specific.
+    // The first entry "ftp=ftp-proxy" takes precedance marking this list as
+    // TYPE_PROXY_PER_SCHEME.
+    {
+      "ftp=ftp-proxy ; foopy",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      NULL,
+      NULL,
+      "ftp-proxy:80",
+      NULL,
+    },
+
+    // Include duplicate entries -- last one wins.
+    {
+      "ftp=ftp1 ; ftp=ftp2 ; ftp=ftp3",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      NULL,
+      NULL,
+      "ftp3:80",
+      NULL,
+    },
+
+    // Only SOCKS proxy present, others being blank.
+    {
+      "socks=foopy",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      NULL,
+      NULL,
+      NULL,
+      "socks4://foopy:1080",
+      },
+
+    // SOCKS proxy present along with other proxies too
+    {
+      "http=httpproxy ; https=httpsproxy ; ftp=ftpproxy ; socks=foopy ",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      "httpproxy:80",
+      "httpsproxy:80",
+      "ftpproxy:80",
+      "socks4://foopy:1080",
+    },
+
+    // SOCKS proxy (with modifier) present along with some proxies
+    // (FTP being blank)
+    {
+      "http=httpproxy ; https=httpsproxy ; socks=socks5://foopy ",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      "httpproxy:80",
+      "httpsproxy:80",
+      NULL,
+      "socks5://foopy:1080",
+      },
+
+    // Include unsupported schemes -- they are discarded.
+    {
+      "crazy=foopy ; foo=bar ; https=myhttpsproxy",
+
+      ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+      NULL,
+      NULL,
+      "myhttpsproxy:80",
+      NULL,
+      NULL,
+    },
+  };
+
+  ProxyConfig config;
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    config.proxy_rules().ParseFromString(tests[i].proxy_rules);
+
+    EXPECT_EQ(tests[i].type, config.proxy_rules().type);
+    ExpectProxyServerEquals(tests[i].single_proxy,
+                            config.proxy_rules().single_proxy);
+    ExpectProxyServerEquals(tests[i].proxy_for_http,
+                            config.proxy_rules().proxy_for_http);
+    ExpectProxyServerEquals(tests[i].proxy_for_https,
+                            config.proxy_rules().proxy_for_https);
+    ExpectProxyServerEquals(tests[i].proxy_for_ftp,
+                            config.proxy_rules().proxy_for_ftp);
+    ExpectProxyServerEquals(tests[i].fallback_proxy,
+                            config.proxy_rules().fallback_proxy);
+  }
+}
+
+TEST(ProxyConfigTest, ProxyRulesSetBypassFlag) {
+  // Test whether the did_bypass_proxy() flag is set in proxy info correctly.
+  ProxyConfig::ProxyRules rules;
+  ProxyInfo  result;
+
+  rules.ParseFromString("http=httpproxy:80");
+  rules.bypass_rules.AddRuleFromString(".com");
+
+  rules.Apply(GURL("http://example.com"), &result);
+  EXPECT_TRUE(result.is_direct_only());
+  EXPECT_TRUE(result.did_bypass_proxy());
+
+  rules.Apply(GURL("http://example.org"), &result);
+  EXPECT_FALSE(result.is_direct());
+  EXPECT_FALSE(result.did_bypass_proxy());
+
+  // Try with reversed bypass rules.
+  rules.reverse_bypass = true;
+
+  rules.Apply(GURL("http://example.org"), &result);
+  EXPECT_TRUE(result.is_direct_only());
+  EXPECT_TRUE(result.did_bypass_proxy());
+
+  rules.Apply(GURL("http://example.com"), &result);
+  EXPECT_FALSE(result.is_direct());
+  EXPECT_FALSE(result.did_bypass_proxy());
+}
+
+}  // namespace
+}  // namespace net
diff --git a/src/net/proxy/proxy_info.cc b/src/net/proxy/proxy_info.cc
new file mode 100644
index 0000000..26018cf
--- /dev/null
+++ b/src/net/proxy/proxy_info.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/proxy_info.h"
+
+#include "net/proxy/proxy_retry_info.h"
+
+namespace net {
+
+ProxyInfo::ProxyInfo()
+    : config_id_(ProxyConfig::kInvalidConfigID),
+      config_source_(PROXY_CONFIG_SOURCE_UNKNOWN),
+      did_bypass_proxy_(false),
+      did_use_pac_script_(false) {
+}
+
+ProxyInfo::~ProxyInfo() {
+}
+
+void ProxyInfo::Use(const ProxyInfo& other) {
+  proxy_list_ = other.proxy_list_;
+  proxy_retry_info_ = other.proxy_retry_info_;
+  config_id_ = other.config_id_;
+  config_source_ = other.config_source_;
+  did_bypass_proxy_ = other.did_bypass_proxy_;
+  did_use_pac_script_ = other.did_use_pac_script_;
+}
+
+void ProxyInfo::UseDirect() {
+  Reset();
+  proxy_list_.SetSingleProxyServer(ProxyServer::Direct());
+}
+
+void ProxyInfo::UseDirectWithBypassedProxy() {
+  UseDirect();
+  did_bypass_proxy_ = true;
+}
+
+void ProxyInfo::UseNamedProxy(const std::string& proxy_uri_list) {
+  Reset();
+  proxy_list_.Set(proxy_uri_list);
+}
+
+void ProxyInfo::UseProxyServer(const ProxyServer& proxy_server) {
+  Reset();
+  proxy_list_.SetSingleProxyServer(proxy_server);
+}
+
+std::string ProxyInfo::ToPacString() const {
+  return proxy_list_.ToPacString();
+}
+
+bool ProxyInfo::Fallback(const BoundNetLog& net_log) {
+  return proxy_list_.Fallback(&proxy_retry_info_, net_log);
+}
+
+void ProxyInfo::DeprioritizeBadProxies(
+    const ProxyRetryInfoMap& proxy_retry_info) {
+  proxy_list_.DeprioritizeBadProxies(proxy_retry_info);
+}
+
+void ProxyInfo::RemoveProxiesWithoutScheme(int scheme_bit_field) {
+  proxy_list_.RemoveProxiesWithoutScheme(scheme_bit_field);
+}
+
+void ProxyInfo::Reset() {
+  proxy_list_.Clear();
+  proxy_retry_info_.clear();
+  config_id_ = ProxyConfig::kInvalidConfigID;
+  config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN;
+  did_bypass_proxy_ = false;
+  did_use_pac_script_ = false;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_info.h b/src/net/proxy/proxy_info.h
new file mode 100644
index 0000000..d0fa523
--- /dev/null
+++ b/src/net/proxy/proxy_info.h
@@ -0,0 +1,154 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_INFO_H_
+#define NET_PROXY_PROXY_INFO_H_
+
+#include <string>
+
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_list.h"
+#include "net/proxy/proxy_retry_info.h"
+#include "net/proxy/proxy_server.h"
+
+namespace net {
+
+// This object holds proxy information returned by ResolveProxy.
+class NET_EXPORT ProxyInfo {
+ public:
+  ProxyInfo();
+  ~ProxyInfo();
+  // Default copy-constructor and assignment operator are OK!
+
+  // Uses the same proxy server as the given |proxy_info|.
+  void Use(const ProxyInfo& proxy_info);
+
+  // Uses a direct connection.
+  void UseDirect();
+
+  // Uses a direct connection. did_bypass_proxy() will return true to indicate
+  // that the direct connection is the result of configured proxy bypass rules.
+  void UseDirectWithBypassedProxy();
+
+  // Uses a specific proxy server, of the form:
+  //   proxy-uri = [<scheme> "://"] <hostname> [":" <port>]
+  // This may optionally be a semi-colon delimited list of <proxy-uri>.
+  // It is OK to have LWS between entries.
+  void UseNamedProxy(const std::string& proxy_uri_list);
+
+  // Sets the proxy list to a single entry, |proxy_server|.
+  void UseProxyServer(const ProxyServer& proxy_server);
+
+  // Parses from the given PAC result.
+  void UsePacString(const std::string& pac_string) {
+    proxy_list_.SetFromPacString(pac_string);
+  }
+
+  // Returns true if this proxy info specifies a direct connection.
+  bool is_direct() const {
+    // We don't implicitly fallback to DIRECT unless it was added to the list.
+    if (is_empty())
+      return false;
+    return proxy_list_.Get().is_direct();
+  }
+
+  bool is_direct_only() const {
+    return is_direct() && proxy_list_.size() == 1 && proxy_retry_info_.empty();
+  }
+
+  // Returns true if the first valid proxy server is an https proxy.
+  bool is_https() const {
+    if (is_empty())
+      return false;
+    return proxy_server().is_https();
+  }
+
+  // Returns true if the first valid proxy server is an http proxy.
+  bool is_http() const {
+    if (is_empty())
+      return false;
+    return proxy_server().is_http();
+  }
+
+  // Returns true if the first valid proxy server is a socks server.
+  bool is_socks() const {
+    if (is_empty())
+      return false;
+    return proxy_server().is_socks();
+  }
+
+  // Returns true if this proxy info has no proxies left to try.
+  bool is_empty() const {
+    return proxy_list_.IsEmpty();
+  }
+
+  // Returns true if this proxy resolution is using a direct connection due to
+  // proxy bypass rules.
+  bool did_bypass_proxy() const {
+    return did_bypass_proxy_;
+  }
+
+  // Returns true if the proxy resolution was done using a PAC script.
+  bool did_use_pac_script() const {
+    return did_use_pac_script_;
+  }
+
+  // Returns the first valid proxy server. is_empty() must be false to be able
+  // to call this function.
+  const ProxyServer& proxy_server() const { return proxy_list_.Get(); }
+
+  // Returns the source for configuration settings used for proxy resolution.
+  ProxyConfigSource config_source() const { return config_source_; }
+
+  // See description in ProxyList::ToPacString().
+  std::string ToPacString() const;
+
+  // Marks the current proxy as bad. Returns true if there is another proxy
+  // available to try in proxy list_.
+  bool Fallback(const BoundNetLog& net_log);
+
+  // De-prioritizes the proxies that we have cached as not working, by moving
+  // them to the end of the proxy list.
+  void DeprioritizeBadProxies(const ProxyRetryInfoMap& proxy_retry_info);
+
+  // Deletes any entry which doesn't have one of the specified proxy schemes.
+  void RemoveProxiesWithoutScheme(int scheme_bit_field);
+
+  ProxyConfig::ID config_id() const { return config_id_; }
+
+ private:
+  friend class ProxyService;
+
+  const ProxyRetryInfoMap& proxy_retry_info() const {
+    return proxy_retry_info_;
+  }
+
+  // Reset proxy and config settings.
+  void Reset();
+
+  // The ordered list of proxy servers (including DIRECT attempts) remaining to
+  // try. If proxy_list_ is empty, then there is nothing left to fall back to.
+  ProxyList proxy_list_;
+
+  // List of proxies that have been tried already.
+  ProxyRetryInfoMap proxy_retry_info_;
+
+  // This value identifies the proxy config used to initialize this object.
+  ProxyConfig::ID config_id_;
+
+  // The source of the proxy settings used,
+  ProxyConfigSource config_source_;
+
+  // Whether the proxy result represent a proxy bypass.
+  bool did_bypass_proxy_;
+
+  // Whether we used a PAC script for resolving the proxy.
+  bool did_use_pac_script_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_INFO_H_
diff --git a/src/net/proxy/proxy_info_unittest.cc b/src/net/proxy/proxy_info_unittest.cc
new file mode 100644
index 0000000..377cff3
--- /dev/null
+++ b/src/net/proxy/proxy_info_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/proxy/proxy_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+TEST(ProxyInfoTest, ProxyInfoIsDirectOnly) {
+  // Test the is_direct_only() predicate.
+  ProxyInfo info;
+
+  // An empty ProxyInfo is not considered direct.
+  EXPECT_FALSE(info.is_direct_only());
+
+  info.UseDirect();
+  EXPECT_TRUE(info.is_direct_only());
+
+  info.UsePacString("DIRECT");
+  EXPECT_TRUE(info.is_direct_only());
+
+  info.UsePacString("PROXY myproxy:80");
+  EXPECT_FALSE(info.is_direct_only());
+
+  info.UsePacString("DIRECT; PROXY myproxy:80");
+  EXPECT_TRUE(info.is_direct());
+  EXPECT_FALSE(info.is_direct_only());
+
+  info.UsePacString("PROXY myproxy:80; DIRECT");
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_FALSE(info.is_direct_only());
+  // After falling back to direct, we shouldn't consider it DIRECT only.
+  EXPECT_TRUE(info.Fallback(BoundNetLog()));
+  EXPECT_TRUE(info.is_direct());
+  EXPECT_FALSE(info.is_direct_only());
+}
+
+}  // namespace
+}  // namespace net
diff --git a/src/net/proxy/proxy_list.cc b/src/net/proxy/proxy_list.cc
new file mode 100644
index 0000000..2057d50
--- /dev/null
+++ b/src/net/proxy/proxy_list.cc
@@ -0,0 +1,204 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_list.h"
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/string_tokenizer.h"
+#include "base/time.h"
+#include "net/proxy/proxy_server.h"
+
+using base::TimeDelta;
+using base::TimeTicks;
+
+namespace net {
+
+ProxyList::ProxyList() {
+}
+
+ProxyList::~ProxyList() {
+}
+
+void ProxyList::Set(const std::string& proxy_uri_list) {
+  proxies_.clear();
+  StringTokenizer str_tok(proxy_uri_list, ";");
+  while (str_tok.GetNext()) {
+    ProxyServer uri = ProxyServer::FromURI(
+        str_tok.token_begin(), str_tok.token_end(), ProxyServer::SCHEME_HTTP);
+    // Silently discard malformed inputs.
+    if (uri.is_valid())
+      proxies_.push_back(uri);
+  }
+}
+
+void ProxyList::SetSingleProxyServer(const ProxyServer& proxy_server) {
+  proxies_.clear();
+  if (proxy_server.is_valid())
+    proxies_.push_back(proxy_server);
+}
+
+void ProxyList::DeprioritizeBadProxies(
+    const ProxyRetryInfoMap& proxy_retry_info) {
+  // Partition the proxy list in two:
+  //   (1) the known bad proxies
+  //   (2) everything else
+  std::vector<ProxyServer> good_proxies;
+  std::vector<ProxyServer> bad_proxies;
+
+  std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
+  for (; iter != proxies_.end(); ++iter) {
+    ProxyRetryInfoMap::const_iterator bad_proxy =
+        proxy_retry_info.find(iter->ToURI());
+    if (bad_proxy != proxy_retry_info.end()) {
+      // This proxy is bad. Check if it's time to retry.
+      if (bad_proxy->second.bad_until >= TimeTicks::Now()) {
+        // still invalid.
+        bad_proxies.push_back(*iter);
+        continue;
+      }
+    }
+    good_proxies.push_back(*iter);
+  }
+
+  // "proxies_ = good_proxies + bad_proxies"
+  proxies_.swap(good_proxies);
+  proxies_.insert(proxies_.end(), bad_proxies.begin(), bad_proxies.end());
+}
+
+bool ProxyList::HasUntriedProxies(
+    const ProxyRetryInfoMap& proxy_retry_info) const {
+  std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
+  for (; iter != proxies_.end(); ++iter) {
+    ProxyRetryInfoMap::const_iterator bad_proxy =
+        proxy_retry_info.find(iter->ToURI());
+    if (bad_proxy != proxy_retry_info.end()) {
+      // This proxy is bad. Check if it's time to retry.
+      if (bad_proxy->second.bad_until >= TimeTicks::Now()) {
+        continue;
+      }
+    }
+    // Either we've found the entry in the retry map and it's expired or we
+    // didn't find a corresponding entry in the retry map. In either case, we
+    // have a proxy to try.
+    return true;
+  }
+  return false;
+}
+
+void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) {
+  for (std::vector<ProxyServer>::iterator it = proxies_.begin();
+       it != proxies_.end(); ) {
+    if (!(scheme_bit_field & it->scheme())) {
+      it = proxies_.erase(it);
+      continue;
+    }
+    ++it;
+  }
+}
+
+void ProxyList::Clear() {
+  proxies_.clear();
+}
+
+bool ProxyList::IsEmpty() const {
+  return proxies_.empty();
+}
+
+size_t ProxyList::size() const {
+  return proxies_.size();
+}
+
+const ProxyServer& ProxyList::Get() const {
+  DCHECK(!proxies_.empty());
+  return proxies_[0];
+}
+
+void ProxyList::SetFromPacString(const std::string& pac_string) {
+  StringTokenizer entry_tok(pac_string, ";");
+  proxies_.clear();
+  while (entry_tok.GetNext()) {
+    ProxyServer uri = ProxyServer::FromPacString(
+        entry_tok.token_begin(), entry_tok.token_end());
+    // Silently discard malformed inputs.
+    if (uri.is_valid())
+      proxies_.push_back(uri);
+  }
+
+  // If we failed to parse anything from the PAC results list, fallback to
+  // DIRECT (this basically means an error in the PAC script).
+  if (proxies_.empty()) {
+    proxies_.push_back(ProxyServer::Direct());
+  }
+}
+
+std::string ProxyList::ToPacString() const {
+  std::string proxy_list;
+  std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
+  for (; iter != proxies_.end(); ++iter) {
+    if (!proxy_list.empty())
+      proxy_list += ";";
+    proxy_list += iter->ToPacString();
+  }
+  return proxy_list.empty() ? std::string() : proxy_list;
+}
+
+bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info,
+                         const BoundNetLog& net_log) {
+
+  // TODO(eroman): It would be good if instead of removing failed proxies
+  // from the list, we simply annotated them with the error code they failed
+  // with. Of course, ProxyService::ReconsiderProxyAfterError() would need to
+  // be given this information by the network transaction.
+  //
+  // The advantage of this approach is when the network transaction
+  // fails, we could output the full list of proxies that were attempted, and
+  // why each one of those failed (as opposed to just the last failure).
+  //
+  // And also, before failing the transaction wholesale, we could go back and
+  // retry the "bad proxies" which we never tried to begin with.
+  // (RemoveBadProxies would annotate them as 'expected bad' rather then delete
+  // them from the list, so we would know what they were).
+
+  if (proxies_.empty()) {
+    NOTREACHED();
+    return false;
+  }
+  UpdateRetryInfoOnFallback(proxy_retry_info, net_log);
+
+  // Remove this proxy from our list.
+  proxies_.erase(proxies_.begin());
+  return !proxies_.empty();
+}
+
+void ProxyList::UpdateRetryInfoOnFallback(
+    ProxyRetryInfoMap* proxy_retry_info, const BoundNetLog& net_log) const {
+  // Number of minutes to wait before retrying a bad proxy server.
+  const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5);
+
+  if (proxies_.empty()) {
+    NOTREACHED();
+    return;
+  }
+
+  if (!proxies_[0].is_direct()) {
+    std::string key = proxies_[0].ToURI();
+    // Mark this proxy as bad.
+    ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key);
+    if (iter != proxy_retry_info->end()) {
+      // TODO(nsylvain): This is not the first time we get this. We should
+      // double the retry time. Bug 997660.
+      iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay;
+    } else {
+      ProxyRetryInfo retry_info;
+      retry_info.current_delay = kProxyRetryDelay;
+      retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay;
+      (*proxy_retry_info)[key] = retry_info;
+    }
+    net_log.AddEvent(NetLog::TYPE_PROXY_LIST_FALLBACK,
+                     NetLog::StringCallback("bad_proxy", &key));
+  }
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_list.h b/src/net/proxy/proxy_list.h
new file mode 100644
index 0000000..209dd67
--- /dev/null
+++ b/src/net/proxy/proxy_list.h
@@ -0,0 +1,90 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_PROXY_LIST_H_
+#define NET_PROXY_PROXY_LIST_H_
+
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+#include "net/proxy/proxy_retry_info.h"
+
+namespace net {
+
+class ProxyServer;
+
+// This class is used to hold a list of proxies returned by GetProxyForUrl or
+// manually configured. It handles proxy fallback if multiple servers are
+// specified.
+class NET_EXPORT_PRIVATE ProxyList {
+ public:
+  ProxyList();
+  ~ProxyList();
+
+  // Initializes the proxy list to a string containing one or more proxy servers
+  // delimited by a semicolon.
+  void Set(const std::string& proxy_uri_list);
+
+  // Set the proxy list to a single entry, |proxy_server|.
+  void SetSingleProxyServer(const ProxyServer& proxy_server);
+
+  // De-prioritizes the proxies that we have cached as not working, by moving
+  // them to the end of the fallback list.
+  void DeprioritizeBadProxies(const ProxyRetryInfoMap& proxy_retry_info);
+
+  // Returns true if this proxy list contains at least one proxy that is
+  // not currently present in |proxy_retry_info|.
+  bool HasUntriedProxies(const ProxyRetryInfoMap& proxy_retry_info) const;
+
+  // Delete any entry which doesn't have one of the specified proxy schemes.
+  // |scheme_bit_field| is a bunch of ProxyServer::Scheme bitwise ORed together.
+  void RemoveProxiesWithoutScheme(int scheme_bit_field);
+
+  // Clear the proxy list.
+  void Clear();
+
+  // Returns true if there is nothing left in the ProxyList.
+  bool IsEmpty() const;
+
+  // Returns the number of proxy servers in this list.
+  size_t size() const;
+
+  // Returns the first proxy server in the list. It is only valid to call
+  // this if !IsEmpty().
+  const ProxyServer& Get() const;
+
+  // Sets the list by parsing the pac result |pac_string|.
+  // Some examples for |pac_string|:
+  //   "DIRECT"
+  //   "PROXY foopy1"
+  //   "PROXY foopy1; SOCKS4 foopy2:1188"
+  // Does a best-effort parse, and silently discards any errors.
+  void SetFromPacString(const std::string& pac_string);
+
+  // Returns a PAC-style semicolon-separated list of valid proxy servers.
+  // For example: "PROXY xxx.xxx.xxx.xxx:xx; SOCKS yyy.yyy.yyy:yy".
+  std::string ToPacString() const;
+
+  // Marks the current proxy server as bad and deletes it from the list.  The
+  // list of known bad proxies is given by proxy_retry_info.  Returns true if
+  // there is another server available in the list.
+  bool Fallback(ProxyRetryInfoMap* proxy_retry_info,
+                const BoundNetLog& net_log);
+
+  // Updates |proxy_retry_info| to indicate that the first proxy in the list
+  // is bad. This is distinct from Fallback(), above, to allow updating proxy
+  // retry information without modifying a given transction's proxy list.
+  void UpdateRetryInfoOnFallback(ProxyRetryInfoMap* proxy_retry_info,
+                                 const BoundNetLog& net_log) const;
+
+ private:
+  // List of proxies.
+  std::vector<ProxyServer> proxies_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_LIST_H_
diff --git a/src/net/proxy/proxy_list_unittest.cc b/src/net/proxy/proxy_list_unittest.cc
new file mode 100644
index 0000000..470a900
--- /dev/null
+++ b/src/net/proxy/proxy_list_unittest.cc
@@ -0,0 +1,183 @@
+// Copyright (c) 2006-2008 The Chromium Authors. 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/proxy/proxy_list.h"
+
+#include "net/proxy/proxy_server.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+// Test parsing from a PAC string.
+TEST(ProxyListTest, SetFromPacString) {
+  const struct {
+    const char* pac_input;
+    const char* pac_output;
+  } tests[] = {
+    // Valid inputs:
+    {  "PROXY foopy:10",
+       "PROXY foopy:10",
+    },
+    {  " DIRECT",  // leading space.
+       "DIRECT",
+    },
+    {  "PROXY foopy1 ; proxy foopy2;\t DIRECT",
+       "PROXY foopy1:80;PROXY foopy2:80;DIRECT",
+    },
+    {  "proxy foopy1 ; SOCKS foopy2",
+       "PROXY foopy1:80;SOCKS foopy2:1080",
+    },
+    // Try putting DIRECT first.
+    {  "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
+       "DIRECT;PROXY foopy1:80;DIRECT;SOCKS5 foopy2:1080;DIRECT",
+    },
+    // Try putting DIRECT consecutively.
+    {  "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT",
+       "DIRECT;PROXY foopy1:80;DIRECT;DIRECT",
+    },
+
+    // Invalid inputs (parts which aren't understood get
+    // silently discarded):
+    //
+    // If the proxy list string parsed to empty, automatically fall-back to
+    // DIRECT.
+    {  "PROXY-foopy:10",
+       "DIRECT",
+    },
+    {  "PROXY",
+       "DIRECT",
+    },
+    {  "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
+       "PROXY foopy1:80;SOCKS5 foopy2:1080",
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    ProxyList list;
+    list.SetFromPacString(tests[i].pac_input);
+    EXPECT_EQ(tests[i].pac_output, list.ToPacString());
+    EXPECT_FALSE(list.IsEmpty());
+  }
+}
+
+TEST(ProxyListTest, RemoveProxiesWithoutScheme) {
+  const struct {
+    const char* pac_input;
+    int filter;
+    const char* filtered_pac_output;
+  } tests[] = {
+    {  "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT",
+       // Remove anything that isn't HTTP or DIRECT.
+       ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP,
+       "PROXY foopy:10;PROXY foopy3:80;DIRECT",
+    },
+    {  "PROXY foopy:10 ; SOCKS5 foopy2",
+       // Remove anything that isn't HTTP or SOCKS5.
+       ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_SOCKS4,
+       "",
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    ProxyList list;
+    list.SetFromPacString(tests[i].pac_input);
+    list.RemoveProxiesWithoutScheme(tests[i].filter);
+    EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString());
+  }
+}
+
+TEST(ProxyListTest, HasUntriedProxies) {
+  // As in DeprioritizeBadProxies, we use a lengthy timeout to avoid depending
+  // on the current time.
+  ProxyRetryInfo proxy_retry_info;
+  proxy_retry_info.bad_until =
+      base::TimeTicks::Now() + base::TimeDelta::FromDays(1);
+
+  // An empty list has nothing to try.
+  {
+    ProxyList list;
+    ProxyRetryInfoMap proxy_retry_info;
+    EXPECT_FALSE(list.HasUntriedProxies(proxy_retry_info));
+  }
+
+  // A list with one bad proxy has something to try. With two bad proxies,
+  // there's nothing to try.
+  {
+    ProxyList list;
+    list.SetFromPacString("PROXY bad1:80; PROXY bad2:80");
+    ProxyRetryInfoMap retry_info_map;
+    retry_info_map["bad1:80"] = proxy_retry_info;
+    EXPECT_TRUE(list.HasUntriedProxies(retry_info_map));
+    retry_info_map["bad2:80"] = proxy_retry_info;
+    EXPECT_FALSE(list.HasUntriedProxies(retry_info_map));
+  }
+
+  // A list with one bad proxy and a DIRECT entry has something to try.
+  {
+    ProxyList list;
+    list.SetFromPacString("PROXY bad1:80; DIRECT");
+    ProxyRetryInfoMap retry_info_map;
+    retry_info_map["bad1:80"] = proxy_retry_info;
+    EXPECT_TRUE(list.HasUntriedProxies(retry_info_map));
+  }
+}
+
+TEST(ProxyListTest, DeprioritizeBadProxies) {
+  // Retry info that marks a proxy as being bad for a *very* long time (to avoid
+  // the test depending on the current time.)
+  ProxyRetryInfo proxy_retry_info;
+  proxy_retry_info.bad_until =
+      base::TimeTicks::Now() + base::TimeDelta::FromDays(1);
+
+  // Call DeprioritizeBadProxies with an empty map -- should have no effect.
+  {
+    ProxyList list;
+    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
+
+    ProxyRetryInfoMap retry_info_map;
+    list.DeprioritizeBadProxies(retry_info_map);
+    EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
+              list.ToPacString());
+  }
+
+  // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad.
+  // These proxies should be retried last.
+  {
+    ProxyList list;
+    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
+
+    ProxyRetryInfoMap retry_info_map;
+    retry_info_map["foopy1:80"] = proxy_retry_info;
+    retry_info_map["foopy3:80"] = proxy_retry_info;
+    retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
+
+    list.DeprioritizeBadProxies(retry_info_map);
+
+    EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80;PROXY foopy3:80",
+              list.ToPacString());
+  }
+
+  // Call DeprioritizeBadProxies where ALL of the proxies are marked as bad.
+  // This should have no effect on the order.
+  {
+    ProxyList list;
+    list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
+
+    ProxyRetryInfoMap retry_info_map;
+    retry_info_map["foopy1:80"] = proxy_retry_info;
+    retry_info_map["foopy2:80"] = proxy_retry_info;
+    retry_info_map["foopy3:80"] = proxy_retry_info;
+
+    list.DeprioritizeBadProxies(retry_info_map);
+
+    EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
+              list.ToPacString());
+  }
+}
+
+}  // namesapce
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver.h b/src/net/proxy/proxy_resolver.h
new file mode 100644
index 0000000..6b63407
--- /dev/null
+++ b/src/net/proxy/proxy_resolver.h
@@ -0,0 +1,90 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_H_
+#define NET_PROXY_PROXY_RESOLVER_H_
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/string16.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/completion_callback.h"
+#include "net/base/load_states.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_resolver_script_data.h"
+
+namespace net {
+
+class BoundNetLog;
+class ProxyInfo;
+
+// Interface for "proxy resolvers". A ProxyResolver fills in a list of proxies
+// to use for a particular URL. Generally the backend for a ProxyResolver is
+// a PAC script, but it doesn't need to be. ProxyResolver can service multiple
+// requests at a time.
+class NET_EXPORT_PRIVATE ProxyResolver {
+ public:
+  // Opaque pointer type, to return a handle to cancel outstanding requests.
+  typedef void* RequestHandle;
+
+  // See |expects_pac_bytes()| for the meaning of |expects_pac_bytes|.
+  explicit ProxyResolver(bool expects_pac_bytes)
+      : expects_pac_bytes_(expects_pac_bytes) {}
+
+  virtual ~ProxyResolver() {}
+
+  // Gets a list of proxy servers to use for |url|. If the request will
+  // complete asynchronously returns ERR_IO_PENDING and notifies the result
+  // by running |callback|.  If the result code is OK then
+  // the request was successful and |results| contains the proxy
+  // resolution information.  In the case of asynchronous completion
+  // |*request| is written to, and can be passed to CancelRequest().
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const net::CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) = 0;
+
+  // Cancels |request|.
+  virtual void CancelRequest(RequestHandle request) = 0;
+
+  // Gets the LoadState for |request|.
+  virtual LoadState GetLoadState(RequestHandle request) const = 0;
+
+  // Gets the LoadState for |request|. May be called from another thread.
+  virtual LoadState GetLoadStateThreadSafe(RequestHandle request) const = 0;
+
+  // The PAC script backend can be specified to the ProxyResolver either via
+  // URL, or via the javascript text itself.  If |expects_pac_bytes| is true,
+  // then the ProxyResolverScriptData passed to SetPacScript() should
+  // contain the actual script bytes rather than just the URL.
+  bool expects_pac_bytes() const { return expects_pac_bytes_; }
+
+  virtual void CancelSetPacScript() = 0;
+
+  // Frees any unneeded memory held by the resolver, e.g. garbage in the JS
+  // engine.  Most subclasses don't need to do anything, so we provide a default
+  // no-op implementation.
+  virtual void PurgeMemory() {}
+
+  // Called to set the PAC script backend to use.
+  // Returns ERR_IO_PENDING in the case of asynchronous completion, and notifies
+  // the result through |callback|.
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& pac_script,
+      const net::CompletionCallback& callback) = 0;
+
+  // Optional shutdown code to be run before destruction. This is only used
+  // by the multithreaded runner to signal cleanup from origin thread
+  virtual void Shutdown() {}
+
+ private:
+  const bool expects_pac_bytes_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyResolver);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_H_
diff --git a/src/net/proxy/proxy_resolver_error_observer.h b/src/net/proxy/proxy_resolver_error_observer.h
new file mode 100644
index 0000000..9176c2f
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_error_observer.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_H_
+#define NET_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_H_
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// Interface for observing JavaScript error messages from PAC scripts. The
+// default implementation of the ProxyResolverJSBindings takes a class
+// implementing this interface and forwards all JavaScript errors related to
+// PAC scripts.
+class NET_EXPORT_PRIVATE ProxyResolverErrorObserver {
+ public:
+  ProxyResolverErrorObserver() {}
+  virtual ~ProxyResolverErrorObserver() {}
+
+  // Handler for when an error is encountered. |line_number| may be -1
+  // if a line number is not applicable to this error. |error| is a message
+  // describing the error.
+  virtual void OnPACScriptError(int line_number, const string16& error) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProxyResolverErrorObserver);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_ERROR_OBSERVER_H_
diff --git a/src/net/proxy/proxy_resolver_js_bindings.cc b/src/net/proxy/proxy_resolver_js_bindings.cc
new file mode 100644
index 0000000..84dcafd
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_js_bindings.cc
@@ -0,0 +1,291 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_resolver_js_bindings.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/values.h"
+#include "net/base/address_list.h"
+#include "net/base/host_cache.h"
+#include "net/base/host_resolver.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_util.h"
+#include "net/proxy/proxy_resolver_error_observer.h"
+#include "net/proxy/proxy_resolver_request_context.h"
+#include "net/proxy/sync_host_resolver.h"
+
+namespace net {
+
+namespace {
+
+// TTL for the per-request DNS cache. Applies to both successful and failed
+// DNS resolutions.
+const unsigned kCacheEntryTTLSeconds = 5 * 60;
+
+// Returns event parameters for a PAC error message (line number + message).
+Value* NetLogErrorCallback(int line_number,
+                           const string16* message,
+                           NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetInteger("line_number", line_number);
+  dict->SetString("message", *message);
+  return dict;
+}
+
+// ProxyResolverJSBindings implementation.
+class DefaultJSBindings : public ProxyResolverJSBindings {
+ public:
+  DefaultJSBindings(SyncHostResolver* host_resolver,
+                    NetLog* net_log,
+                    ProxyResolverErrorObserver* error_observer)
+      : host_resolver_(host_resolver),
+        net_log_(net_log),
+        error_observer_(error_observer) {
+  }
+
+  // Handler for "alert(message)".
+  virtual void Alert(const string16& message) OVERRIDE {
+    VLOG(1) << "PAC-alert: " << message;
+
+    // Send to the NetLog.
+    LogEventToCurrentRequestAndGlobally(
+        NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+        NetLog::StringCallback("message", &message));
+  }
+
+  // Handler for "myIpAddress()".
+  // TODO(eroman): Perhaps enumerate the interfaces directly, using
+  // getifaddrs().
+  virtual bool MyIpAddress(std::string* first_ip_address) OVERRIDE {
+    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
+                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS);
+
+    bool ok = MyIpAddressImpl(first_ip_address);
+
+    LogEventToCurrentRequest(NetLog::PHASE_END,
+                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS);
+    return ok;
+  }
+
+  // Handler for "myIpAddressEx()".
+  virtual bool MyIpAddressEx(std::string* ip_address_list) OVERRIDE {
+    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
+                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX);
+
+    bool ok = MyIpAddressExImpl(ip_address_list);
+
+    LogEventToCurrentRequest(NetLog::PHASE_END,
+                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX);
+    return ok;
+  }
+
+  // Handler for "dnsResolve(host)".
+  virtual bool DnsResolve(const std::string& host,
+                          std::string* first_ip_address) OVERRIDE {
+    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
+                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE);
+
+    bool ok = DnsResolveImpl(host, first_ip_address);
+
+    LogEventToCurrentRequest(NetLog::PHASE_END,
+                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE);
+    return ok;
+  }
+
+  // Handler for "dnsResolveEx(host)".
+  virtual bool DnsResolveEx(const std::string& host,
+                            std::string* ip_address_list) OVERRIDE {
+    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
+                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX);
+
+    bool ok = DnsResolveExImpl(host, ip_address_list);
+
+    LogEventToCurrentRequest(NetLog::PHASE_END,
+                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX);
+    return ok;
+  }
+
+  // Handler for when an error is encountered. |line_number| may be -1.
+  virtual void OnError(int line_number, const string16& message) OVERRIDE {
+    // Send to the chrome log.
+    if (line_number == -1)
+      VLOG(1) << "PAC-error: " << message;
+    else
+      VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message;
+
+    // Send the error to the NetLog.
+    LogEventToCurrentRequestAndGlobally(
+        NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
+        base::Bind(&NetLogErrorCallback, line_number, &message));
+
+    if (error_observer_.get())
+      error_observer_->OnPACScriptError(line_number, message);
+  }
+
+  virtual void Shutdown() OVERRIDE {
+    host_resolver_->Shutdown();
+  }
+
+ private:
+  bool MyIpAddressImpl(std::string* first_ip_address) {
+    std::string my_hostname = GetHostName();
+    if (my_hostname.empty())
+      return false;
+    return DnsResolveImpl(my_hostname, first_ip_address);
+  }
+
+  bool MyIpAddressExImpl(std::string* ip_address_list) {
+    std::string my_hostname = GetHostName();
+    if (my_hostname.empty())
+      return false;
+    return DnsResolveExImpl(my_hostname, ip_address_list);
+  }
+
+  bool DnsResolveImpl(const std::string& host,
+                      std::string* first_ip_address) {
+    // Do a sync resolve of the hostname (port doesn't matter).
+    // Disable IPv6 results. We do this because the PAC specification isn't
+    // really IPv6 friendly, and Internet Explorer also restricts to IPv4.
+    // Consequently a lot of existing PAC scripts assume they will only get
+    // IPv4 results, and will misbehave if they get an IPv6 result.
+    // See http://crbug.com/24641 for more details.
+    HostResolver::RequestInfo info(HostPortPair(host, 80));
+    info.set_address_family(ADDRESS_FAMILY_IPV4);
+    AddressList address_list;
+
+    int result = DnsResolveHelper(info, &address_list);
+    if (result != OK)
+      return false;
+
+    // There may be multiple results; we will just use the first one.
+    // This returns empty string on failure.
+    *first_ip_address = address_list.front().ToStringWithoutPort();
+    if (first_ip_address->empty())
+      return false;
+
+    return true;
+  }
+
+  bool DnsResolveExImpl(const std::string& host,
+                        std::string* ip_address_list) {
+    // Do a sync resolve of the hostname (port doesn't matter).
+    HostResolver::RequestInfo info(HostPortPair(host, 80));
+    AddressList address_list;
+    int result = DnsResolveHelper(info, &address_list);
+
+    if (result != OK)
+      return false;
+
+    // Stringify all of the addresses in the address list, separated
+    // by semicolons.
+    std::string address_list_str;
+    for (AddressList::const_iterator iter = address_list.begin();
+         iter != address_list.end(); ++iter) {
+      if (!address_list_str.empty())
+        address_list_str += ";";
+      const std::string address_string = iter->ToStringWithoutPort();
+      if (address_string.empty())
+        return false;
+      address_list_str += address_string;
+    }
+
+    *ip_address_list = address_list_str;
+    return true;
+  }
+
+  // Helper to execute a synchronous DNS resolve, using the per-request
+  // DNS cache if there is one.
+  int DnsResolveHelper(const HostResolver::RequestInfo& info,
+                       AddressList* address_list) {
+    HostCache::Key cache_key(info.hostname(),
+                             info.address_family(),
+                             info.host_resolver_flags());
+
+    HostCache* host_cache = current_request_context() ?
+        current_request_context()->host_cache : NULL;
+
+    // First try to service this request from the per-request DNS cache.
+    // (we cache DNS failures much more aggressively within the context
+    // of a FindProxyForURL() request).
+    if (host_cache) {
+      const HostCache::Entry* entry =
+          host_cache->Lookup(cache_key, base::TimeTicks::Now());
+      if (entry) {
+        if (entry->error == OK)
+          *address_list = entry->addrlist;
+        return entry->error;
+      }
+    }
+
+    // Otherwise ask the host resolver.
+    const BoundNetLog* net_log = GetNetLogForCurrentRequest();
+    int result = host_resolver_->Resolve(info,
+                                         address_list,
+                                         net_log ? *net_log : BoundNetLog());
+
+    // Save the result back to the per-request DNS cache.
+    if (host_cache) {
+      host_cache->Set(cache_key, HostCache::Entry(result, *address_list),
+                      base::TimeTicks::Now(),
+                      base::TimeDelta::FromSeconds(kCacheEntryTTLSeconds));
+    }
+
+    return result;
+  }
+
+  // May return NULL.
+  const BoundNetLog* GetNetLogForCurrentRequest() {
+    if (!current_request_context())
+      return NULL;
+    return current_request_context()->net_log;
+  }
+
+  void LogEventToCurrentRequest(
+      NetLog::EventPhase phase,
+      NetLog::EventType type) {
+    const BoundNetLog* net_log = GetNetLogForCurrentRequest();
+    if (net_log)
+      net_log->AddEntry(type, phase);
+  }
+
+  void LogEventToCurrentRequest(
+      NetLog::EventPhase phase,
+      NetLog::EventType type,
+      const NetLog::ParametersCallback& parameters_callback) {
+    const BoundNetLog* net_log = GetNetLogForCurrentRequest();
+    if (net_log)
+      net_log->AddEntry(type, phase, parameters_callback);
+  }
+
+  void LogEventToCurrentRequestAndGlobally(
+      NetLog::EventType type,
+      const NetLog::ParametersCallback& parameters_callback) {
+    LogEventToCurrentRequest(NetLog::PHASE_NONE, type, parameters_callback);
+
+    // Emit to the global NetLog event stream.
+    if (net_log_)
+      net_log_->AddGlobalEntry(type, parameters_callback);
+  }
+
+  scoped_ptr<SyncHostResolver> host_resolver_;
+  NetLog* net_log_;
+  scoped_ptr<ProxyResolverErrorObserver> error_observer_;
+  DISALLOW_COPY_AND_ASSIGN(DefaultJSBindings);
+};
+
+}  // namespace
+
+// static
+ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault(
+    SyncHostResolver* host_resolver,
+    NetLog* net_log,
+    ProxyResolverErrorObserver* error_observer) {
+  return new DefaultJSBindings(host_resolver, net_log, error_observer);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_js_bindings.h b/src/net/proxy/proxy_resolver_js_bindings.h
new file mode 100644
index 0000000..f201707
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_js_bindings.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_JS_BINDINGS_H_
+#define NET_PROXY_PROXY_RESOLVER_JS_BINDINGS_H_
+
+#include <string>
+
+#include "base/string16.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class HostResolver;
+class NetLog;
+class ProxyResolverErrorObserver;
+struct ProxyResolverRequestContext;
+class SyncHostResolver;
+
+// Interface for the javascript bindings.
+class NET_EXPORT_PRIVATE ProxyResolverJSBindings {
+ public:
+  ProxyResolverJSBindings() : current_request_context_(NULL) {}
+
+  virtual ~ProxyResolverJSBindings() {}
+
+  // Handler for "alert(message)"
+  virtual void Alert(const string16& message) = 0;
+
+  // Handler for "myIpAddress()". Returns true on success and fills
+  // |*first_ip_address| with the result.
+  virtual bool MyIpAddress(std::string* first_ip_address) = 0;
+
+  // Handler for "myIpAddressEx()". Returns true on success and fills
+  // |*ip_address_list| with the result.
+  //
+  // This is a Microsoft extension to PAC for IPv6, see:
+  // http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
+
+  virtual bool MyIpAddressEx(std::string* ip_address_list) = 0;
+
+  // Handler for "dnsResolve(host)". Returns true on success and fills
+  // |*first_ip_address| with the result.
+  virtual bool DnsResolve(const std::string& host,
+                          std::string* first_ip_address) = 0;
+
+  // Handler for "dnsResolveEx(host)". Returns true on success and fills
+  // |*ip_address_list| with the result.
+  //
+  // This is a Microsoft extension to PAC for IPv6, see:
+  // http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
+  virtual bool DnsResolveEx(const std::string& host,
+                            std::string* ip_address_list) = 0;
+
+  // Handler for when an error is encountered. |line_number| may be -1
+  // if a line number is not applicable to this error.
+  virtual void OnError(int line_number, const string16& error) = 0;
+
+  // Called before the thread running the proxy resolver is stopped.
+  virtual void Shutdown() = 0;
+
+  // Creates a default javascript bindings implementation that will:
+  //   - Send script error messages to both VLOG(1) and the NetLog.
+  //   - Send script alert()s to both VLOG(1) and the NetLog.
+  //   - Use the provided host resolver to service dnsResolve().
+  //
+  // Takes ownership of |host_resolver| and |error_observer| (the latter can
+  // be NULL).
+  static ProxyResolverJSBindings* CreateDefault(
+      SyncHostResolver* host_resolver,
+      NetLog* net_log,
+      ProxyResolverErrorObserver* error_observer);
+
+  // Sets details about the currently executing FindProxyForURL() request.
+  void set_current_request_context(
+      ProxyResolverRequestContext* current_request_context) {
+    current_request_context_ = current_request_context;
+  }
+
+  // Retrieves details about the currently executing FindProxyForURL() request.
+  ProxyResolverRequestContext* current_request_context() {
+    return current_request_context_;
+  }
+
+ private:
+  ProxyResolverRequestContext* current_request_context_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_JS_BINDINGS_H_
diff --git a/src/net/proxy/proxy_resolver_js_bindings_unittest.cc b/src/net/proxy/proxy_resolver_js_bindings_unittest.cc
new file mode 100644
index 0000000..f4d5a30
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_js_bindings_unittest.cc
@@ -0,0 +1,378 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_resolver_js_bindings.h"
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_util.h"
+#include "net/base/address_list.h"
+#include "net/base/host_cache.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/net_util.h"
+#include "net/base/test_completion_callback.h"
+#include "net/proxy/proxy_resolver_request_context.h"
+#include "net/proxy/sync_host_resolver.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_STARBOARD)
+// Starboard doesn't implement GetHostName.
+#define MAYBE_MyIpAddress DISABLED_MyIpAddress
+#else
+#define MAYBE_MyIpAddress MyIpAddress
+#endif
+
+namespace net {
+
+namespace {
+
+// This is a HostResolver that synchronously resolves all hosts to the
+// following address list of length 3:
+//     192.168.1.1
+//     172.22.34.1
+//     200.100.1.2
+class MockHostResolverWithMultipleResults : public SyncHostResolver {
+ public:
+  // HostResolver methods:
+  virtual int Resolve(const HostResolver::RequestInfo& info,
+                      AddressList* addresses,
+                      const BoundNetLog& bound_net_log) OVERRIDE {
+    return ParseAddressList("192.168.1.1,172.22.34.1,200.100.1.2", "",
+                            addresses);
+  }
+
+  virtual void Shutdown() OVERRIDE {}
+
+ private:
+  virtual ~MockHostResolverWithMultipleResults() {}
+};
+
+class MockFailingHostResolver : public SyncHostResolver {
+ public:
+  MockFailingHostResolver() : count_(0) {}
+
+  // HostResolver methods:
+  virtual int Resolve(const HostResolver::RequestInfo& info,
+                      AddressList* addresses,
+                      const BoundNetLog& bound_net_log) OVERRIDE {
+    count_++;
+    return ERR_NAME_NOT_RESOLVED;
+  }
+
+  virtual void Shutdown() OVERRIDE {}
+
+  // Returns the number of times Resolve() has been called.
+  int count() const { return count_; }
+  void ResetCount() { count_ = 0; }
+
+ private:
+  int count_;
+};
+
+class MockSyncHostResolver : public SyncHostResolver {
+ public:
+  MockSyncHostResolver() {
+    resolver_.set_synchronous_mode(true);
+  }
+
+  virtual int Resolve(const HostResolver::RequestInfo& info,
+                      AddressList* addresses,
+                      const BoundNetLog& bound_net_log) OVERRIDE {
+    return resolver_.Resolve(info, addresses, CompletionCallback(), NULL,
+                             bound_net_log);
+  }
+
+  virtual void Shutdown() OVERRIDE {}
+
+  RuleBasedHostResolverProc* rules() {
+    return resolver_.rules();
+  }
+
+ private:
+  MockHostResolver resolver_;
+};
+
+TEST(ProxyResolverJSBindingsTest, DnsResolve) {
+  MockSyncHostResolver* host_resolver = new MockSyncHostResolver;
+
+  // Get a hold of a DefaultJSBindings* (it is a hidden impl class).
+  scoped_ptr<ProxyResolverJSBindings> bindings(
+      ProxyResolverJSBindings::CreateDefault(host_resolver, NULL, NULL));
+
+  std::string ip_address;
+
+  // Empty string is not considered a valid host (even though on some systems
+  // requesting this will resolve to localhost).
+  host_resolver->rules()->AddSimulatedFailure("");
+  EXPECT_FALSE(bindings->DnsResolve("", &ip_address));
+
+  // Should call through to the HostResolver.
+  host_resolver->rules()->AddRule("google.com", "192.168.1.1");
+  EXPECT_TRUE(bindings->DnsResolve("google.com", &ip_address));
+  EXPECT_EQ("192.168.1.1", ip_address);
+
+  // Resolve failures should give empty string.
+  host_resolver->rules()->AddSimulatedFailure("fail");
+  EXPECT_FALSE(bindings->DnsResolve("fail", &ip_address));
+
+  // TODO(eroman): would be nice to have an IPV6 test here too, but that
+  // won't work on all systems.
+}
+
+TEST(ProxyResolverJSBindingsTest, MAYBE_MyIpAddress) {
+  MockSyncHostResolver* host_resolver = new MockSyncHostResolver;
+
+  // Get a hold of a DefaultJSBindings* (it is a hidden impl class).
+  scoped_ptr<ProxyResolverJSBindings> bindings(
+      ProxyResolverJSBindings::CreateDefault(host_resolver, NULL, NULL));
+
+  // Our IP address is always going to be 127.0.0.1, since we are using a
+  // mock host resolver.
+  std::string my_ip_address;
+  EXPECT_TRUE(bindings->MyIpAddress(&my_ip_address));
+
+  EXPECT_EQ("127.0.0.1", my_ip_address);
+}
+
+// Tests that the regular PAC functions restrict results to IPv4,
+// but that the Microsoft extensions to PAC do not. We test this
+// by seeing whether ADDRESS_FAMILY_IPV4 or ADDRESS_FAMILY_UNSPECIFIED
+// was passed into to the host resolver.
+//
+//   Restricted to IPv4 address family:
+//     myIpAddress()
+//     dnsResolve()
+//
+//   Unrestricted address family:
+//     myIpAddressEx()
+//     dnsResolveEx()
+TEST(ProxyResolverJSBindingsTest, RestrictAddressFamily) {
+  MockSyncHostResolver* host_resolver = new MockSyncHostResolver;
+
+  // Get a hold of a DefaultJSBindings* (it is a hidden impl class).
+  scoped_ptr<ProxyResolverJSBindings> bindings(
+      ProxyResolverJSBindings::CreateDefault(host_resolver, NULL, NULL));
+
+  // Make it so requests resolve to particular address patterns based on family:
+  //  IPV4_ONLY --> 192.168.1.*
+  //  UNSPECIFIED --> 192.168.2.1
+  host_resolver->rules()->AddRuleForAddressFamily(
+      "foo", ADDRESS_FAMILY_IPV4, "192.168.1.1");
+  host_resolver->rules()->AddRuleForAddressFamily(
+      "*", ADDRESS_FAMILY_IPV4, "192.168.1.2");
+  host_resolver->rules()->AddRuleForAddressFamily(
+      "foo", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.1");
+  host_resolver->rules()->AddRuleForAddressFamily(
+      "*", ADDRESS_FAMILY_UNSPECIFIED, "192.168.2.2");
+
+  // Verify that our mock setups works as expected, and we get different results
+  // depending if the address family was IPV4_ONLY or not.
+  HostResolver::RequestInfo info(HostPortPair("foo", 80));
+  AddressList address_list;
+  EXPECT_EQ(OK, host_resolver->Resolve(info, &address_list, BoundNetLog()));
+  ASSERT_FALSE(address_list.empty());
+  EXPECT_EQ("192.168.2.1", address_list.front().ToStringWithoutPort());
+
+  info.set_address_family(ADDRESS_FAMILY_IPV4);
+  EXPECT_EQ(OK, host_resolver->Resolve(info, &address_list, BoundNetLog()));
+  ASSERT_FALSE(address_list.empty());
+  EXPECT_EQ("192.168.1.1", address_list.front().ToStringWithoutPort());
+
+  std::string ip_address;
+  // Now the actual test.
+#if !defined(OS_STARBOARD)
+  EXPECT_TRUE(bindings->MyIpAddress(&ip_address));
+  EXPECT_EQ("192.168.1.2", ip_address);  // IPv4 restricted.
+#endif
+
+  EXPECT_TRUE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_EQ("192.168.1.1", ip_address);  // IPv4 restricted.
+
+  EXPECT_TRUE(bindings->DnsResolve("foo2", &ip_address));
+  EXPECT_EQ("192.168.1.2", ip_address);  // IPv4 restricted.
+
+#if !defined(OS_STARBOARD)
+  EXPECT_TRUE(bindings->MyIpAddressEx(&ip_address));
+  EXPECT_EQ("192.168.2.2", ip_address);  // Unrestricted.
+#endif
+
+  EXPECT_TRUE(bindings->DnsResolveEx("foo", &ip_address));
+  EXPECT_EQ("192.168.2.1", ip_address);  // Unrestricted.
+
+  EXPECT_TRUE(bindings->DnsResolveEx("foo2", &ip_address));
+  EXPECT_EQ("192.168.2.2", ip_address);  // Unrestricted.
+}
+
+// Test that myIpAddressEx() and dnsResolveEx() both return a semi-colon
+// separated list of addresses (as opposed to the non-Ex versions which
+// just return the first result).
+TEST(ProxyResolverJSBindingsTest, ExFunctionsReturnList) {
+  SyncHostResolver* host_resolver =
+      new MockHostResolverWithMultipleResults;
+
+  // Get a hold of a DefaultJSBindings* (it is a hidden impl class).
+  scoped_ptr<ProxyResolverJSBindings> bindings(
+      ProxyResolverJSBindings::CreateDefault(host_resolver, NULL, NULL));
+
+  std::string ip_addresses;
+
+#if !defined(OS_STARBOARD)
+  EXPECT_TRUE(bindings->MyIpAddressEx(&ip_addresses));
+  EXPECT_EQ("192.168.1.1;172.22.34.1;200.100.1.2", ip_addresses);
+#endif
+
+  EXPECT_TRUE(bindings->DnsResolveEx("FOO", &ip_addresses));
+  EXPECT_EQ("192.168.1.1;172.22.34.1;200.100.1.2", ip_addresses);
+}
+
+TEST(ProxyResolverJSBindingsTest, PerRequestDNSCache) {
+  MockFailingHostResolver* host_resolver = new MockFailingHostResolver;
+
+  // Get a hold of a DefaultJSBindings* (it is a hidden impl class).
+  scoped_ptr<ProxyResolverJSBindings> bindings(
+      ProxyResolverJSBindings::CreateDefault(host_resolver, NULL, NULL));
+
+  std::string ip_address;
+
+  // Call DnsResolve() 4 times for the same hostname -- this should issue
+  // 4 separate calls to the underlying host resolver, since there is no
+  // current request context.
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_EQ(4, host_resolver->count());
+
+  host_resolver->ResetCount();
+
+  // Now setup a per-request context, and try the same experiment -- we
+  // expect the underlying host resolver to receive only 1 request this time,
+  // since it will service the others from the per-request DNS cache.
+  const unsigned kMaxCacheEntries = 50;
+  HostCache cache(kMaxCacheEntries);
+  ProxyResolverRequestContext context(NULL, &cache);
+  bindings->set_current_request_context(&context);
+
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolve("foo", &ip_address));
+  EXPECT_EQ(1, host_resolver->count());
+
+  host_resolver->ResetCount();
+
+  // The "Ex" version shares this same cache, however since the flags
+  // are different it won't reuse this particular entry.
+  EXPECT_FALSE(bindings->DnsResolveEx("foo", &ip_address));
+  EXPECT_EQ(1, host_resolver->count());
+  EXPECT_FALSE(bindings->DnsResolveEx("foo", &ip_address));
+  EXPECT_FALSE(bindings->DnsResolveEx("foo", &ip_address));
+  EXPECT_EQ(1, host_resolver->count());
+
+  bindings->set_current_request_context(NULL);
+}
+
+// Test that when a binding is called, it logs to the per-request NetLog.
+TEST(ProxyResolverJSBindingsTest, NetLog) {
+  MockFailingHostResolver* host_resolver = new MockFailingHostResolver;
+
+  CapturingNetLog global_log;
+
+  // Get a hold of a DefaultJSBindings* (it is a hidden impl class).
+  scoped_ptr<ProxyResolverJSBindings> bindings(
+      ProxyResolverJSBindings::CreateDefault(
+          host_resolver, &global_log, NULL));
+
+  // Attach a capturing NetLog as the current request's log stream.
+  CapturingNetLog log;
+  BoundNetLog bound_log(BoundNetLog::Make(&log, NetLog::SOURCE_NONE));
+  ProxyResolverRequestContext context(&bound_log, NULL);
+  bindings->set_current_request_context(&context);
+
+  std::string ip_address;
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+  ASSERT_EQ(0u, entries.size());
+
+  // Call all the bindings. Each call should be logging something to
+  // our NetLog.
+
+  bindings->MyIpAddress(&ip_address);
+
+  log.GetEntries(&entries);
+  EXPECT_EQ(2u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS));
+
+  bindings->MyIpAddressEx(&ip_address);
+
+  log.GetEntries(&entries);
+  EXPECT_EQ(4u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 2, NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 3, NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX));
+
+  bindings->DnsResolve("foo", &ip_address);
+
+  log.GetEntries(&entries);
+  EXPECT_EQ(6u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 4, NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 5, NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE));
+
+  bindings->DnsResolveEx("foo", &ip_address);
+
+  log.GetEntries(&entries);
+  EXPECT_EQ(8u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 6, NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 7, NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX));
+
+  // Nothing has been emitted globally yet.
+  net::CapturingNetLog::CapturedEntryList global_log_entries;
+  global_log.GetEntries(&global_log_entries);
+  EXPECT_EQ(0u, global_log_entries.size());
+
+  bindings->OnError(30, string16());
+
+  log.GetEntries(&entries);
+  EXPECT_EQ(9u, entries.size());
+  EXPECT_TRUE(LogContainsEvent(
+      entries, 8, NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
+      NetLog::PHASE_NONE));
+
+  // We also emit errors to the top-level log stream.
+  global_log.GetEntries(&global_log_entries);
+  EXPECT_EQ(1u, global_log_entries.size());
+  EXPECT_TRUE(LogContainsEvent(
+      global_log_entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
+      NetLog::PHASE_NONE));
+
+  bindings->Alert(string16());
+
+  log.GetEntries(&entries);
+  EXPECT_EQ(10u, entries.size());
+  EXPECT_TRUE(LogContainsEvent(
+      entries, 9, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+      NetLog::PHASE_NONE));
+
+  // We also emit javascript alerts to the top-level log stream.
+  global_log.GetEntries(&global_log_entries);
+  EXPECT_EQ(2u, global_log_entries.size());
+  EXPECT_TRUE(LogContainsEvent(
+      global_log_entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
+      NetLog::PHASE_NONE));
+}
+
+}  // namespace
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_mac.cc b/src/net/proxy/proxy_resolver_mac.cc
new file mode 100644
index 0000000..a5a05af
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_mac.cc
@@ -0,0 +1,215 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/proxy_resolver_mac.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "base/logging.h"
+#include "base/mac/foundation_util.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_server.h"
+
+#if defined(OS_IOS)
+#include <CFNetwork/CFProxySupport.h>
+#else
+#include <CoreServices/CoreServices.h>
+#endif
+
+namespace {
+
+// Utility function to map a CFProxyType to a ProxyServer::Scheme.
+// If the type is unknown, returns ProxyServer::SCHEME_INVALID.
+net::ProxyServer::Scheme GetProxyServerScheme(CFStringRef proxy_type) {
+  if (CFEqual(proxy_type, kCFProxyTypeNone))
+    return net::ProxyServer::SCHEME_DIRECT;
+  if (CFEqual(proxy_type, kCFProxyTypeHTTP))
+    return net::ProxyServer::SCHEME_HTTP;
+  if (CFEqual(proxy_type, kCFProxyTypeHTTPS)) {
+    // The "HTTPS" on the Mac side here means "proxy applies to https://" URLs;
+    // the proxy itself is still expected to be an HTTP proxy.
+    return net::ProxyServer::SCHEME_HTTP;
+  }
+  if (CFEqual(proxy_type, kCFProxyTypeSOCKS)) {
+    // We can't tell whether this was v4 or v5. We will assume it is
+    // v5 since that is the only version OS X supports.
+    return net::ProxyServer::SCHEME_SOCKS5;
+  }
+  return net::ProxyServer::SCHEME_INVALID;
+}
+
+// Callback for CFNetworkExecuteProxyAutoConfigurationURL. |client| is a pointer
+// to a CFTypeRef.  This stashes either |error| or |proxies| in that location.
+void ResultCallback(void* client, CFArrayRef proxies, CFErrorRef error) {
+  DCHECK((proxies != NULL) == (error == NULL));
+
+  CFTypeRef* result_ptr = reinterpret_cast<CFTypeRef*>(client);
+  DCHECK(result_ptr != NULL);
+  DCHECK(*result_ptr == NULL);
+
+  if (error != NULL) {
+    *result_ptr = CFRetain(error);
+  } else {
+    *result_ptr = CFRetain(proxies);
+  }
+  CFRunLoopStop(CFRunLoopGetCurrent());
+}
+
+}  // namespace
+
+namespace net {
+
+ProxyResolverMac::ProxyResolverMac()
+    : ProxyResolver(false /*expects_pac_bytes*/) {
+}
+
+ProxyResolverMac::~ProxyResolverMac() {}
+
+// Gets the proxy information for a query URL from a PAC. Implementation
+// inspired by http://developer.apple.com/samplecode/CFProxySupportTool/
+int ProxyResolverMac::GetProxyForURL(const GURL& query_url,
+                                     ProxyInfo* results,
+                                     const CompletionCallback& /*callback*/,
+                                     RequestHandle* /*request*/,
+                                     const BoundNetLog& net_log) {
+  base::mac::ScopedCFTypeRef<CFStringRef> query_ref(
+      base::SysUTF8ToCFStringRef(query_url.spec()));
+  base::mac::ScopedCFTypeRef<CFURLRef> query_url_ref(
+      CFURLCreateWithString(kCFAllocatorDefault,
+                            query_ref.get(),
+                            NULL));
+  if (!query_url_ref.get())
+    return ERR_FAILED;
+  base::mac::ScopedCFTypeRef<CFStringRef> pac_ref(
+      base::SysUTF8ToCFStringRef(
+          script_data_->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT ?
+              std::string() : script_data_->url().spec()));
+  base::mac::ScopedCFTypeRef<CFURLRef> pac_url_ref(
+      CFURLCreateWithString(kCFAllocatorDefault,
+                            pac_ref.get(),
+                            NULL));
+  if (!pac_url_ref.get())
+    return ERR_FAILED;
+
+  // Work around <rdar://problem/5530166>. This dummy call to
+  // CFNetworkCopyProxiesForURL initializes some state within CFNetwork that is
+  // required by CFNetworkExecuteProxyAutoConfigurationURL.
+
+  CFArrayRef dummy_result = CFNetworkCopyProxiesForURL(query_url_ref.get(),
+                                                       NULL);
+  if (dummy_result)
+    CFRelease(dummy_result);
+
+  // We cheat here. We need to act as if we were synchronous, so we pump the
+  // runloop ourselves. Our caller moved us to a new thread anyway, so this is
+  // OK to do. (BTW, CFNetworkExecuteProxyAutoConfigurationURL returns a
+  // runloop source we need to release despite its name.)
+
+  CFTypeRef result = NULL;
+  CFStreamClientContext context = { 0, &result, NULL, NULL, NULL };
+  base::mac::ScopedCFTypeRef<CFRunLoopSourceRef> runloop_source(
+      CFNetworkExecuteProxyAutoConfigurationURL(pac_url_ref.get(),
+                                                query_url_ref.get(),
+                                                ResultCallback,
+                                                &context));
+  if (!runloop_source)
+    return ERR_FAILED;
+
+  const CFStringRef private_runloop_mode =
+      CFSTR("org.chromium.ProxyResolverMac");
+
+  CFRunLoopAddSource(CFRunLoopGetCurrent(), runloop_source.get(),
+                     private_runloop_mode);
+  CFRunLoopRunInMode(private_runloop_mode, DBL_MAX, false);
+  CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop_source.get(),
+                        private_runloop_mode);
+  DCHECK(result != NULL);
+
+  if (CFGetTypeID(result) == CFErrorGetTypeID()) {
+    // TODO(avi): do something better than this
+    CFRelease(result);
+    return ERR_FAILED;
+  }
+  base::mac::ScopedCFTypeRef<CFArrayRef> proxy_array_ref(
+      base::mac::CFCastStrict<CFArrayRef>(result));
+  DCHECK(proxy_array_ref != NULL);
+
+  // This string will be an ordered list of <proxy-uri> entries, separated by
+  // semi-colons. It is the format that ProxyInfo::UseNamedProxy() expects.
+  //    proxy-uri = [<proxy-scheme>"://"]<proxy-host>":"<proxy-port>
+  // (This also includes entries for direct connection, as "direct://").
+  std::string proxy_uri_list;
+
+  CFIndex proxy_array_count = CFArrayGetCount(proxy_array_ref.get());
+  for (CFIndex i = 0; i < proxy_array_count; ++i) {
+    CFDictionaryRef proxy_dictionary = base::mac::CFCastStrict<CFDictionaryRef>(
+        CFArrayGetValueAtIndex(proxy_array_ref.get(), i));
+    DCHECK(proxy_dictionary != NULL);
+
+    // The dictionary may have the following keys:
+    // - kCFProxyTypeKey : The type of the proxy
+    // - kCFProxyHostNameKey
+    // - kCFProxyPortNumberKey : The meat we're after.
+    // - kCFProxyUsernameKey
+    // - kCFProxyPasswordKey : Despite the existence of these keys in the
+    //                         documentation, they're never populated. Even if a
+    //                         username/password were to be set in the network
+    //                         proxy system preferences, we'd need to fetch it
+    //                         from the Keychain ourselves. CFProxy is such a
+    //                         tease.
+    // - kCFProxyAutoConfigurationURLKey : If the PAC file specifies another
+    //                                     PAC file, I'm going home.
+
+    CFStringRef proxy_type = base::mac::GetValueFromDictionary<CFStringRef>(
+        proxy_dictionary, kCFProxyTypeKey);
+    ProxyServer proxy_server = ProxyServer::FromDictionary(
+        GetProxyServerScheme(proxy_type),
+        proxy_dictionary,
+        kCFProxyHostNameKey,
+        kCFProxyPortNumberKey);
+    if (!proxy_server.is_valid())
+      continue;
+
+    if (!proxy_uri_list.empty())
+      proxy_uri_list += ";";
+    proxy_uri_list += proxy_server.ToURI();
+  }
+
+  if (!proxy_uri_list.empty())
+    results->UseNamedProxy(proxy_uri_list);
+  // Else do nothing (results is already guaranteed to be in the default state).
+
+  return OK;
+}
+
+void ProxyResolverMac::CancelRequest(RequestHandle request) {
+  NOTREACHED();
+}
+
+LoadState ProxyResolverMac::GetLoadState(RequestHandle request) const {
+  NOTREACHED();
+  return LOAD_STATE_IDLE;
+}
+
+LoadState ProxyResolverMac::GetLoadStateThreadSafe(
+    RequestHandle request) const {
+  return LOAD_STATE_IDLE;
+}
+
+void ProxyResolverMac::CancelSetPacScript() {
+  NOTREACHED();
+}
+
+int ProxyResolverMac::SetPacScript(
+    const scoped_refptr<ProxyResolverScriptData>& script_data,
+    const CompletionCallback& /*callback*/) {
+  script_data_ = script_data;
+  return OK;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_mac.h b/src/net/proxy/proxy_resolver_mac.h
new file mode 100644
index 0000000..2aafce2
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_mac.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_MAC_H_
+#define NET_PROXY_PROXY_RESOLVER_MAC_H_
+
+#include "base/compiler_specific.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_resolver.h"
+
+namespace net {
+
+// Implementation of ProxyResolver that uses the Mac CFProxySupport to implement
+// proxies.
+class NET_EXPORT ProxyResolverMac : public ProxyResolver {
+ public:
+  ProxyResolverMac();
+  virtual ~ProxyResolverMac();
+
+  // ProxyResolver methods:
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const net::CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE;
+
+  virtual void CancelRequest(RequestHandle request) OVERRIDE;
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE;
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE;
+
+  virtual void CancelSetPacScript() OVERRIDE;
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const net::CompletionCallback& /*callback*/) OVERRIDE;
+
+ private:
+  scoped_refptr<ProxyResolverScriptData> script_data_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_MAC_H_
diff --git a/src/net/proxy/proxy_resolver_perftest.cc b/src/net/proxy/proxy_resolver_perftest.cc
new file mode 100644
index 0000000..f5994ca
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_perftest.cc
@@ -0,0 +1,219 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/base_paths.h"
+#include "base/compiler_specific.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/perftimer.h"
+#include "base/string_util.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_resolver_js_bindings.h"
+#include "net/proxy/proxy_resolver_v8.h"
+#include "net/proxy/sync_host_resolver.h"
+#include "net/test/test_server.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(OS_WIN)
+#include "net/proxy/proxy_resolver_winhttp.h"
+#elif defined(OS_MACOSX)
+#include "net/proxy/proxy_resolver_mac.h"
+#endif
+
+class MockSyncHostResolver : public net::SyncHostResolver {
+ public:
+  virtual int Resolve(const net::HostResolver::RequestInfo& info,
+                      net::AddressList* addresses,
+                      const net::BoundNetLog& net_log) OVERRIDE {
+    return net::ERR_NAME_NOT_RESOLVED;
+  }
+
+  virtual void Shutdown() OVERRIDE {}
+};
+
+// This class holds the URL to use for resolving, and the expected result.
+// We track the expected result in order to make sure the performance
+// test is actually resolving URLs properly, otherwise the perf numbers
+// are meaningless :-)
+struct PacQuery {
+  const char* query_url;
+  const char* expected_result;
+};
+
+// Entry listing which PAC scripts to load, and which URLs to try resolving.
+// |queries| should be terminated by {NULL, NULL}. A sentinel is used
+// rather than a length, to simplify using initializer lists.
+struct PacPerfTest {
+  const char* pac_name;
+  PacQuery queries[100];
+
+  // Returns the actual number of entries in |queries| (assumes NULL sentinel).
+  int NumQueries() const;
+};
+
+// List of performance tests.
+static PacPerfTest kPerfTests[] = {
+  // This test uses an ad-blocker PAC script. This script is very heavily
+  // regular expression oriented, and has no dependencies on the current
+  // IP address, or DNS resolving of hosts.
+  { "no-ads.pac",
+    { // queries:
+      {"http://www.google.com", "DIRECT"},
+      {"http://www.imdb.com/photos/cmsicons/x", "PROXY 0.0.0.0:3421"},
+      {"http://www.imdb.com/x", "DIRECT"},
+      {"http://www.staples.com/", "DIRECT"},
+      {"http://www.staples.com/pixeltracker/x", "PROXY 0.0.0.0:3421"},
+      {"http://www.staples.com/pixel/x", "DIRECT"},
+      {"http://www.foobar.com", "DIRECT"},
+      {"http://www.foobarbaz.com/x/y/z", "DIRECT"},
+      {"http://www.testurl1.com/index.html", "DIRECT"},
+      {"http://www.testurl2.com", "DIRECT"},
+      {"https://www.sample/pirate/arrrrrr", "DIRECT"},
+      {NULL, NULL}
+    },
+  },
+};
+
+int PacPerfTest::NumQueries() const {
+  for (size_t i = 0; i < arraysize(queries); ++i) {
+    if (queries[i].query_url == NULL)
+      return i;
+  }
+  NOTREACHED();  // Bad definition.
+  return 0;
+}
+
+// The number of URLs to resolve when testing a PAC script.
+const int kNumIterations = 500;
+
+// Helper class to run through all the performance tests using the specified
+// proxy resolver implementation.
+class PacPerfSuiteRunner {
+ public:
+  // |resolver_name| is the label used when logging the results.
+  PacPerfSuiteRunner(net::ProxyResolver* resolver,
+                     const std::string& resolver_name)
+      : resolver_(resolver),
+        resolver_name_(resolver_name),
+        test_server_(
+            net::TestServer::TYPE_HTTP,
+            net::TestServer::kLocalhost,
+            FilePath(FILE_PATH_LITERAL("net/data/proxy_resolver_perftest"))) {
+  }
+
+  void RunAllTests() {
+    ASSERT_TRUE(test_server_.Start());
+    for (size_t i = 0; i < arraysize(kPerfTests); ++i) {
+      const PacPerfTest& test_data = kPerfTests[i];
+      RunTest(test_data.pac_name,
+              test_data.queries,
+              test_data.NumQueries());
+    }
+  }
+
+ private:
+  void RunTest(const std::string& script_name,
+               const PacQuery* queries,
+               int queries_len) {
+    if (!resolver_->expects_pac_bytes()) {
+      GURL pac_url =
+          test_server_.GetURL(std::string("files/") + script_name);
+      int rv = resolver_->SetPacScript(
+          net::ProxyResolverScriptData::FromURL(pac_url),
+          net::CompletionCallback());
+      EXPECT_EQ(net::OK, rv);
+    } else {
+      LoadPacScriptIntoResolver(script_name);
+    }
+
+    // Do a query to warm things up. In the case of internal-fetch proxy
+    // resolvers, the first resolve will be slow since it has to download
+    // the PAC script.
+    {
+      net::ProxyInfo proxy_info;
+      int result = resolver_->GetProxyForURL(
+          GURL("http://www.warmup.com"), &proxy_info, net::CompletionCallback(),
+          NULL, net::BoundNetLog());
+      ASSERT_EQ(net::OK, result);
+    }
+
+    // Start the perf timer.
+    std::string perf_test_name = resolver_name_ + "_" + script_name;
+    PerfTimeLogger timer(perf_test_name.c_str());
+
+    for (int i = 0; i < kNumIterations; ++i) {
+      // Round-robin between URLs to resolve.
+      const PacQuery& query = queries[i % queries_len];
+
+      // Resolve.
+      net::ProxyInfo proxy_info;
+      int result = resolver_->GetProxyForURL(
+          GURL(query.query_url), &proxy_info, net::CompletionCallback(), NULL,
+          net::BoundNetLog());
+
+      // Check that the result was correct. Note that ToPacString() and
+      // ASSERT_EQ() are fast, so they won't skew the results.
+      ASSERT_EQ(net::OK, result);
+      ASSERT_EQ(query.expected_result, proxy_info.ToPacString());
+    }
+
+    // Print how long the test ran for.
+    timer.Done();
+  }
+
+  // Read the PAC script from disk and initialize the proxy resolver with it.
+  void LoadPacScriptIntoResolver(const std::string& script_name) {
+    FilePath path;
+    PathService::Get(base::DIR_SOURCE_ROOT, &path);
+    path = path.AppendASCII("net");
+    path = path.AppendASCII("data");
+    path = path.AppendASCII("proxy_resolver_perftest");
+    path = path.AppendASCII(script_name);
+
+    // Try to read the file from disk.
+    std::string file_contents;
+    bool ok = file_util::ReadFileToString(path, &file_contents);
+
+    // If we can't load the file from disk, something is misconfigured.
+    LOG_IF(ERROR, !ok) << "Failed to read file: " << path.value();
+    ASSERT_TRUE(ok);
+
+    // Load the PAC script into the ProxyResolver.
+    int rv = resolver_->SetPacScript(
+        net::ProxyResolverScriptData::FromUTF8(file_contents),
+        net::CompletionCallback());
+    EXPECT_EQ(net::OK, rv);
+  }
+
+  net::ProxyResolver* resolver_;
+  std::string resolver_name_;
+  net::TestServer test_server_;
+};
+
+#if defined(OS_WIN)
+TEST(ProxyResolverPerfTest, ProxyResolverWinHttp) {
+  net::ProxyResolverWinHttp resolver;
+  PacPerfSuiteRunner runner(&resolver, "ProxyResolverWinHttp");
+  runner.RunAllTests();
+}
+#elif defined(OS_MACOSX)
+TEST(ProxyResolverPerfTest, ProxyResolverMac) {
+  net::ProxyResolverMac resolver;
+  PacPerfSuiteRunner runner(&resolver, "ProxyResolverMac");
+  runner.RunAllTests();
+}
+#endif
+
+TEST(ProxyResolverPerfTest, ProxyResolverV8) {
+  net::ProxyResolverJSBindings* js_bindings =
+      net::ProxyResolverJSBindings::CreateDefault(
+          new MockSyncHostResolver, NULL, NULL);
+
+  net::ProxyResolverV8 resolver(js_bindings);
+  PacPerfSuiteRunner runner(&resolver, "ProxyResolverV8");
+  runner.RunAllTests();
+}
+
diff --git a/src/net/proxy/proxy_resolver_request_context.h b/src/net/proxy/proxy_resolver_request_context.h
new file mode 100644
index 0000000..fdcced1
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_request_context.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_REQUEST_CONTEXT_H_
+#define NET_PROXY_PROXY_RESOLVER_REQUEST_CONTEXT_H_
+
+namespace net {
+
+class HostCache;
+class BoundNetLog;
+
+// This data structure holds state related to an invocation of
+// "FindProxyForURL()". It is used to associate per-request
+// data that can be retrieved by the bindings.
+struct ProxyResolverRequestContext {
+  // All of these pointers are expected to remain valid for duration of
+  // this instance's lifetime.
+  ProxyResolverRequestContext(const BoundNetLog* net_log,
+                              HostCache* host_cache)
+    : net_log(net_log),
+      host_cache(host_cache) {
+  }
+
+  const BoundNetLog* net_log;
+  HostCache* host_cache;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_REQUEST_CONTEXT_H_
diff --git a/src/net/proxy/proxy_resolver_script.h b/src/net/proxy/proxy_resolver_script.h
new file mode 100644
index 0000000..283eff9
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_script.h
@@ -0,0 +1,276 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Akhil Arora <akhil.arora@sun.com>
+ *   Tomi Leppikangas <Tomi.Leppikangas@oulu.fi>
+ *   Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
+#define NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
+
+// The following code was formatted from:
+//   'mozilla/netwerk/base/src/nsProxyAutoConfig.js' (1.55)
+//
+// Using the command:
+//   $ cat nsProxyAutoConfig.js |
+//       awk '/var pacUtils/,/EOF/' |
+//       sed -e 's/^\s*$/""/g' |
+//       sed -e 's/"\s*[+]\s*$/"/g' |
+//       sed -e 's/"$/" \\/g' |
+//       sed -e 's/\/(ipaddr);/\/.exec(ipaddr);/g' |
+//       grep -v '^var pacUtils ='
+#define PROXY_RESOLVER_SCRIPT \
+  "function dnsDomainIs(host, domain) {\n" \
+  "    return (host.length >= domain.length &&\n" \
+  "            host.substring(host.length - domain.length) == domain);\n" \
+  "}\n" \
+  "" \
+  "function dnsDomainLevels(host) {\n" \
+  "    return host.split('.').length-1;\n" \
+  "}\n" \
+  "" \
+  "function convert_addr(ipchars) {\n" \
+  "    var bytes = ipchars.split('.');\n" \
+  "    var result = ((bytes[0] & 0xff) << 24) |\n" \
+  "                 ((bytes[1] & 0xff) << 16) |\n" \
+  "                 ((bytes[2] & 0xff) <<  8) |\n" \
+  "                  (bytes[3] & 0xff);\n" \
+  "    return result;\n" \
+  "}\n" \
+  "" \
+  "function isInNet(ipaddr, pattern, maskstr) {\n" \
+  "    var test = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(ipaddr);\n" \
+  "    if (test == null) {\n" \
+  "        ipaddr = dnsResolve(ipaddr);\n" \
+  "        if (ipaddr == null)\n" \
+  "            return false;\n" \
+  "    } else if (test[1] > 255 || test[2] > 255 || \n" \
+  "               test[3] > 255 || test[4] > 255) {\n" \
+  "        return false;    // not an IP address\n" \
+  "    }\n" \
+  "    var host = convert_addr(ipaddr);\n" \
+  "    var pat  = convert_addr(pattern);\n" \
+  "    var mask = convert_addr(maskstr);\n" \
+  "    return ((host & mask) == (pat & mask));\n" \
+  "    \n" \
+  "}\n" \
+  "" \
+  "function isPlainHostName(host) {\n" \
+  "    return (host.search('\\\\.') == -1);\n" \
+  "}\n" \
+  "" \
+  "function isResolvable(host) {\n" \
+  "    var ip = dnsResolve(host);\n" \
+  "    return (ip != null);\n" \
+  "}\n" \
+  "" \
+  "function localHostOrDomainIs(host, hostdom) {\n" \
+  "    return (host == hostdom) ||\n" \
+  "           (hostdom.lastIndexOf(host + '.', 0) == 0);\n" \
+  "}\n" \
+  "" \
+  "function shExpMatch(url, pattern) {\n" \
+  "   pattern = pattern.replace(/\\./g, '\\\\.');\n" \
+  "   pattern = pattern.replace(/\\*/g, '.*');\n" \
+  "   pattern = pattern.replace(/\\?/g, '.');\n" \
+  "   var newRe = new RegExp('^'+pattern+'$');\n" \
+  "   return newRe.test(url);\n" \
+  "}\n" \
+  "" \
+  "var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" \
+  "" \
+  "var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n" \
+  "" \
+  "function weekdayRange() {\n" \
+  "    function getDay(weekday) {\n" \
+  "        if (weekday in wdays) {\n" \
+  "            return wdays[weekday];\n" \
+  "        }\n" \
+  "        return -1;\n" \
+  "    }\n" \
+  "    var date = new Date();\n" \
+  "    var argc = arguments.length;\n" \
+  "    var wday;\n" \
+  "    if (argc < 1)\n" \
+  "        return false;\n" \
+  "    if (arguments[argc - 1] == 'GMT') {\n" \
+  "        argc--;\n" \
+  "        wday = date.getUTCDay();\n" \
+  "    } else {\n" \
+  "        wday = date.getDay();\n" \
+  "    }\n" \
+  "    var wd1 = getDay(arguments[0]);\n" \
+  "    var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" \
+  "    return (wd1 == -1 || wd2 == -1) ? false\n" \
+  "                                    : (wd1 <= wday && wday <= wd2);\n" \
+  "}\n" \
+  "" \
+  "function dateRange() {\n" \
+  "    function getMonth(name) {\n" \
+  "        if (name in months) {\n" \
+  "            return months[name];\n" \
+  "        }\n" \
+  "        return -1;\n" \
+  "    }\n" \
+  "    var date = new Date();\n" \
+  "    var argc = arguments.length;\n" \
+  "    if (argc < 1) {\n" \
+  "        return false;\n" \
+  "    }\n" \
+  "    var isGMT = (arguments[argc - 1] == 'GMT');\n" \
+  "\n" \
+  "    if (isGMT) {\n" \
+  "        argc--;\n" \
+  "    }\n" \
+  "    // function will work even without explict handling of this case\n" \
+  "    if (argc == 1) {\n" \
+  "        var tmp = parseInt(arguments[0]);\n" \
+  "        if (isNaN(tmp)) {\n" \
+  "            return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" \
+  "getMonth(arguments[0]));\n" \
+  "        } else if (tmp < 32) {\n" \
+  "            return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" \
+  "        } else { \n" \
+  "            return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==\n" \
+  "tmp);\n" \
+  "        }\n" \
+  "    }\n" \
+  "    var year = date.getFullYear();\n" \
+  "    var date1, date2;\n" \
+  "    date1 = new Date(year,  0,  1,  0,  0,  0);\n" \
+  "    date2 = new Date(year, 11, 31, 23, 59, 59);\n" \
+  "    var adjustMonth = false;\n" \
+  "    for (var i = 0; i < (argc >> 1); i++) {\n" \
+  "        var tmp = parseInt(arguments[i]);\n" \
+  "        if (isNaN(tmp)) {\n" \
+  "            var mon = getMonth(arguments[i]);\n" \
+  "            date1.setMonth(mon);\n" \
+  "        } else if (tmp < 32) {\n" \
+  "            adjustMonth = (argc <= 2);\n" \
+  "            date1.setDate(tmp);\n" \
+  "        } else {\n" \
+  "            date1.setFullYear(tmp);\n" \
+  "        }\n" \
+  "    }\n" \
+  "    for (var i = (argc >> 1); i < argc; i++) {\n" \
+  "        var tmp = parseInt(arguments[i]);\n" \
+  "        if (isNaN(tmp)) {\n" \
+  "            var mon = getMonth(arguments[i]);\n" \
+  "            date2.setMonth(mon);\n" \
+  "        } else if (tmp < 32) {\n" \
+  "            date2.setDate(tmp);\n" \
+  "        } else {\n" \
+  "            date2.setFullYear(tmp);\n" \
+  "        }\n" \
+  "    }\n" \
+  "    if (adjustMonth) {\n" \
+  "        date1.setMonth(date.getMonth());\n" \
+  "        date2.setMonth(date.getMonth());\n" \
+  "    }\n" \
+  "    if (isGMT) {\n" \
+  "    var tmp = date;\n" \
+  "        tmp.setFullYear(date.getUTCFullYear());\n" \
+  "        tmp.setMonth(date.getUTCMonth());\n" \
+  "        tmp.setDate(date.getUTCDate());\n" \
+  "        tmp.setHours(date.getUTCHours());\n" \
+  "        tmp.setMinutes(date.getUTCMinutes());\n" \
+  "        tmp.setSeconds(date.getUTCSeconds());\n" \
+  "        date = tmp;\n" \
+  "    }\n" \
+  "    return ((date1 <= date) && (date <= date2));\n" \
+  "}\n" \
+  "" \
+  "function timeRange() {\n" \
+  "    var argc = arguments.length;\n" \
+  "    var date = new Date();\n" \
+  "    var isGMT= false;\n" \
+  "\n" \
+  "    if (argc < 1) {\n" \
+  "        return false;\n" \
+  "    }\n" \
+  "    if (arguments[argc - 1] == 'GMT') {\n" \
+  "        isGMT = true;\n" \
+  "        argc--;\n" \
+  "    }\n" \
+  "\n" \
+  "    var hour = isGMT ? date.getUTCHours() : date.getHours();\n" \
+  "    var date1, date2;\n" \
+  "    date1 = new Date();\n" \
+  "    date2 = new Date();\n" \
+  "\n" \
+  "    if (argc == 1) {\n" \
+  "        return (hour == arguments[0]);\n" \
+  "    } else if (argc == 2) {\n" \
+  "        return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" \
+  "    } else {\n" \
+  "        switch (argc) {\n" \
+  "        case 6:\n" \
+  "            date1.setSeconds(arguments[2]);\n" \
+  "            date2.setSeconds(arguments[5]);\n" \
+  "        case 4:\n" \
+  "            var middle = argc >> 1;\n" \
+  "            date1.setHours(arguments[0]);\n" \
+  "            date1.setMinutes(arguments[1]);\n" \
+  "            date2.setHours(arguments[middle]);\n" \
+  "            date2.setMinutes(arguments[middle + 1]);\n" \
+  "            if (middle == 2) {\n" \
+  "                date2.setSeconds(59);\n" \
+  "            }\n" \
+  "            break;\n" \
+  "        default:\n" \
+  "          throw 'timeRange: bad number of arguments'\n" \
+  "        }\n" \
+  "    }\n" \
+  "\n" \
+  "    if (isGMT) {\n" \
+  "        date.setFullYear(date.getUTCFullYear());\n" \
+  "        date.setMonth(date.getUTCMonth());\n" \
+  "        date.setDate(date.getUTCDate());\n" \
+  "        date.setHours(date.getUTCHours());\n" \
+  "        date.setMinutes(date.getUTCMinutes());\n" \
+  "        date.setSeconds(date.getUTCSeconds());\n" \
+  "    }\n" \
+  "    return ((date1 <= date) && (date <= date2));\n" \
+  "}\n"
+
+// This is a Microsoft extension to PAC for IPv6, see:
+// http://blogs.msdn.com/b/wndp/archive/2006/07/13/ipv6-pac-extensions-v0-9.aspx
+#define PROXY_RESOLVER_SCRIPT_EX \
+  "function isResolvableEx(host) {\n" \
+  "    var ipList = dnsResolveEx(host);\n" \
+  "    return (ipList != '');\n" \
+  "}\n"
+
+#endif  // NET_PROXY_PROXY_RESOLVER_SCRIPT_H_
diff --git a/src/net/proxy/proxy_resolver_script_data.cc b/src/net/proxy/proxy_resolver_script_data.cc
new file mode 100644
index 0000000..dbe1e32
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_script_data.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_resolver_script_data.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+
+namespace net {
+
+// static
+scoped_refptr<ProxyResolverScriptData> ProxyResolverScriptData::FromUTF8(
+    const std::string& utf8) {
+  return new ProxyResolverScriptData(TYPE_SCRIPT_CONTENTS,
+                                     GURL(),
+                                     UTF8ToUTF16(utf8));
+}
+
+// static
+scoped_refptr<ProxyResolverScriptData> ProxyResolverScriptData::FromUTF16(
+    const string16& utf16) {
+  return new ProxyResolverScriptData(TYPE_SCRIPT_CONTENTS, GURL(), utf16);
+}
+
+// static
+scoped_refptr<ProxyResolverScriptData> ProxyResolverScriptData::FromURL(
+    const GURL& url) {
+  return new ProxyResolverScriptData(TYPE_SCRIPT_URL, url, string16());
+}
+
+// static
+scoped_refptr<ProxyResolverScriptData>
+ProxyResolverScriptData::ForAutoDetect() {
+  return new ProxyResolverScriptData(TYPE_AUTO_DETECT, GURL(), string16());
+}
+
+const string16& ProxyResolverScriptData::utf16() const {
+  DCHECK_EQ(TYPE_SCRIPT_CONTENTS, type_);
+  return utf16_;
+}
+
+const GURL& ProxyResolverScriptData::url() const {
+  DCHECK_EQ(TYPE_SCRIPT_URL, type_);
+  return url_;
+}
+
+bool ProxyResolverScriptData::Equals(
+    const ProxyResolverScriptData* other) const {
+  if (type() != other->type())
+    return false;
+
+  switch (type()) {
+    case TYPE_SCRIPT_CONTENTS:
+      return utf16() == other->utf16();
+    case TYPE_SCRIPT_URL:
+      return url() == other->url();
+    case TYPE_AUTO_DETECT:
+      return true;
+  }
+
+  return false;  // Shouldn't be reached.
+}
+
+ProxyResolverScriptData::ProxyResolverScriptData(Type type,
+                                                 const GURL& url,
+                                                 const string16& utf16)
+    : type_(type),
+      url_(url),
+      utf16_(utf16) {
+}
+
+ProxyResolverScriptData::~ProxyResolverScriptData() {}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_script_data.h b/src/net/proxy/proxy_resolver_script_data.h
new file mode 100644
index 0000000..1bfcc1a
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_script_data.h
@@ -0,0 +1,74 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_SCRIPT_DATA_H_
+#define NET_PROXY_PROXY_RESOLVER_SCRIPT_DATA_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/string16.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// Reference-counted wrapper for passing around a PAC script specification.
+// The PAC script can be either specified via a URL, a deferred URL for
+// auto-detect, or the actual javascript program text.
+//
+// This is thread-safe so it can be used by multi-threaded implementations of
+// ProxyResolver to share the data between threads.
+class NET_EXPORT_PRIVATE ProxyResolverScriptData
+    : public base::RefCountedThreadSafe<ProxyResolverScriptData> {
+ public:
+  enum Type {
+    TYPE_SCRIPT_CONTENTS,
+    TYPE_SCRIPT_URL,
+    TYPE_AUTO_DETECT,
+  };
+
+  // Creates a script data given the UTF8 bytes of the content.
+  static scoped_refptr<ProxyResolverScriptData> FromUTF8(
+      const std::string& utf8);
+
+  // Creates a script data given the UTF16 bytes of the content.
+  static scoped_refptr<ProxyResolverScriptData> FromUTF16(
+      const string16& utf16);
+
+  // Creates a script data given a URL to the PAC script.
+  static scoped_refptr<ProxyResolverScriptData> FromURL(const GURL& url);
+
+  // Creates a script data for using an automatically detected PAC URL.
+  static scoped_refptr<ProxyResolverScriptData> ForAutoDetect();
+
+  Type type() const {
+    return type_;
+  }
+
+  // Returns the contents of the script as UTF16.
+  // (only valid for type() == TYPE_SCRIPT_CONTENTS).
+  const string16& utf16() const;
+
+  // Returns the URL of the script.
+  // (only valid for type() == TYPE_SCRIPT_URL).
+  const GURL& url() const;
+
+  // Returns true if |this| matches |other|.
+  bool Equals(const ProxyResolverScriptData* other) const;
+
+ private:
+  friend class base::RefCountedThreadSafe<ProxyResolverScriptData>;
+  ProxyResolverScriptData(Type type,
+                          const GURL& url,
+                          const string16& utf16);
+  virtual ~ProxyResolverScriptData();
+
+
+  const Type type_;
+  const GURL url_;
+  const string16 utf16_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_SCRIPT_DATA_H_
diff --git a/src/net/proxy/proxy_resolver_v8.cc b/src/net/proxy/proxy_resolver_v8.cc
new file mode 100644
index 0000000..5150317
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_v8.cc
@@ -0,0 +1,804 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_resolver_v8.h"
+
+#include <algorithm>
+#include <cstdio>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "base/synchronization/lock.h"
+#include "base/utf_string_conversions.h"
+#include "googleurl/src/gurl.h"
+#include "googleurl/src/url_canon.h"
+#include "net/base/host_cache.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_util.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_resolver_js_bindings.h"
+#include "net/proxy/proxy_resolver_request_context.h"
+#include "net/proxy/proxy_resolver_script.h"
+#include "v8/include/v8.h"
+
+// Notes on the javascript environment:
+//
+// For the majority of the PAC utility functions, we use the same code
+// as Firefox. See the javascript library that proxy_resolver_scipt.h
+// pulls in.
+//
+// In addition, we implement a subset of Microsoft's extensions to PAC.
+// - myIpAddressEx()
+// - dnsResolveEx()
+// - isResolvableEx()
+// - isInNetEx()
+// - sortIpAddressList()
+//
+// It is worth noting that the original PAC specification does not describe
+// the return values on failure. Consequently, there are compatibility
+// differences between browsers on what to return on failure, which are
+// illustrated below:
+//
+// --------------------+-------------+-------------------+--------------
+//                     | Firefox3    | InternetExplorer8 |  --> Us <---
+// --------------------+-------------+-------------------+--------------
+// myIpAddress()       | "127.0.0.1" |  ???              |  "127.0.0.1"
+// dnsResolve()        | null        |  false            |  null
+// myIpAddressEx()     | N/A         |  ""               |  ""
+// sortIpAddressList() | N/A         |  false            |  false
+// dnsResolveEx()      | N/A         |  ""               |  ""
+// isInNetEx()         | N/A         |  false            |  false
+// --------------------+-------------+-------------------+--------------
+//
+// TODO(eroman): The cell above reading ??? means I didn't test it.
+//
+// Another difference is in how dnsResolve() and myIpAddress() are
+// implemented -- whether they should restrict to IPv4 results, or
+// include both IPv4 and IPv6. The following table illustrates the
+// differences:
+//
+// --------------------+-------------+-------------------+--------------
+//                     | Firefox3    | InternetExplorer8 |  --> Us <---
+// --------------------+-------------+-------------------+--------------
+// myIpAddress()       | IPv4/IPv6   |  IPv4             |  IPv4
+// dnsResolve()        | IPv4/IPv6   |  IPv4             |  IPv4
+// isResolvable()      | IPv4/IPv6   |  IPv4             |  IPv4
+// myIpAddressEx()     | N/A         |  IPv4/IPv6        |  IPv4/IPv6
+// dnsResolveEx()      | N/A         |  IPv4/IPv6        |  IPv4/IPv6
+// sortIpAddressList() | N/A         |  IPv4/IPv6        |  IPv4/IPv6
+// isResolvableEx()    | N/A         |  IPv4/IPv6        |  IPv4/IPv6
+// isInNetEx()         | N/A         |  IPv4/IPv6        |  IPv4/IPv6
+// -----------------+-------------+-------------------+--------------
+
+namespace net {
+
+namespace {
+
+// Pseudo-name for the PAC script.
+const char kPacResourceName[] = "proxy-pac-script.js";
+// Pseudo-name for the PAC utility script.
+const char kPacUtilityResourceName[] = "proxy-pac-utility-script.js";
+
+// External string wrapper so V8 can access the UTF16 string wrapped by
+// ProxyResolverScriptData.
+class V8ExternalStringFromScriptData
+    : public v8::String::ExternalStringResource {
+ public:
+  explicit V8ExternalStringFromScriptData(
+      const scoped_refptr<ProxyResolverScriptData>& script_data)
+      : script_data_(script_data) {}
+
+  virtual const uint16_t* data() const OVERRIDE {
+    return reinterpret_cast<const uint16*>(script_data_->utf16().data());
+  }
+
+  virtual size_t length() const OVERRIDE {
+    return script_data_->utf16().size();
+  }
+
+ private:
+  const scoped_refptr<ProxyResolverScriptData> script_data_;
+  DISALLOW_COPY_AND_ASSIGN(V8ExternalStringFromScriptData);
+};
+
+// External string wrapper so V8 can access a string literal.
+class V8ExternalASCIILiteral : public v8::String::ExternalAsciiStringResource {
+ public:
+  // |ascii| must be a NULL-terminated C string, and must remain valid
+  // throughout this object's lifetime.
+  V8ExternalASCIILiteral(const char* ascii, size_t length)
+      : ascii_(ascii), length_(length) {
+    DCHECK(IsStringASCII(ascii));
+  }
+
+  virtual const char* data() const OVERRIDE {
+    return ascii_;
+  }
+
+  virtual size_t length() const OVERRIDE {
+    return length_;
+  }
+
+ private:
+  const char* ascii_;
+  size_t length_;
+  DISALLOW_COPY_AND_ASSIGN(V8ExternalASCIILiteral);
+};
+
+// When creating a v8::String from a C++ string we have two choices: create
+// a copy, or create a wrapper that shares the same underlying storage.
+// For small strings it is better to just make a copy, whereas for large
+// strings there are savings by sharing the storage. This number identifies
+// the cutoff length for when to start wrapping rather than creating copies.
+const size_t kMaxStringBytesForCopy = 256;
+
+// Converts a V8 String to a UTF8 std::string.
+std::string V8StringToUTF8(v8::Handle<v8::String> s) {
+  int len = s->Length();
+  std::string result;
+  if (len > 0)
+    s->WriteUtf8(WriteInto(&result, len + 1));
+  return result;
+}
+
+// Converts a V8 String to a UTF16 string16.
+string16 V8StringToUTF16(v8::Handle<v8::String> s) {
+  int len = s->Length();
+  string16 result;
+  // Note that the reinterpret cast is because on Windows string16 is an alias
+  // to wstring, and hence has character type wchar_t not uint16_t.
+  if (len > 0)
+    s->Write(reinterpret_cast<uint16_t*>(WriteInto(&result, len + 1)), 0, len);
+  return result;
+}
+
+// Converts an ASCII std::string to a V8 string.
+v8::Local<v8::String> ASCIIStringToV8String(const std::string& s) {
+  DCHECK(IsStringASCII(s));
+  return v8::String::New(s.data(), s.size());
+}
+
+// Converts a UTF16 string16 (warpped by a ProxyResolverScriptData) to a
+// V8 string.
+v8::Local<v8::String> ScriptDataToV8String(
+    const scoped_refptr<ProxyResolverScriptData>& s) {
+  if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) {
+    return v8::String::New(
+        reinterpret_cast<const uint16_t*>(s->utf16().data()),
+        s->utf16().size());
+  }
+  return v8::String::NewExternal(new V8ExternalStringFromScriptData(s));
+}
+
+// Converts an ASCII string literal to a V8 string.
+v8::Local<v8::String> ASCIILiteralToV8String(const char* ascii) {
+  DCHECK(IsStringASCII(ascii));
+  size_t length = strlen(ascii);
+  if (length <= kMaxStringBytesForCopy)
+    return v8::String::New(ascii, length);
+  return v8::String::NewExternal(new V8ExternalASCIILiteral(ascii, length));
+}
+
+// Stringizes a V8 object by calling its toString() method. Returns true
+// on success. This may fail if the toString() throws an exception.
+bool V8ObjectToUTF16String(v8::Handle<v8::Value> object,
+                           string16* utf16_result) {
+  if (object.IsEmpty())
+    return false;
+
+  v8::HandleScope scope;
+  v8::Local<v8::String> str_object = object->ToString();
+  if (str_object.IsEmpty())
+    return false;
+  *utf16_result = V8StringToUTF16(str_object);
+  return true;
+}
+
+// Extracts an hostname argument from |args|. On success returns true
+// and fills |*hostname| with the result.
+bool GetHostnameArgument(const v8::Arguments& args, std::string* hostname) {
+  // The first argument should be a string.
+  if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
+    return false;
+
+  const string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString());
+
+  // If the hostname is already in ASCII, simply return it as is.
+  if (IsStringASCII(hostname_utf16)) {
+    *hostname = UTF16ToASCII(hostname_utf16);
+    return true;
+  }
+
+  // Otherwise try to convert it from IDN to punycode.
+  const int kInitialBufferSize = 256;
+  url_canon::RawCanonOutputT<char16, kInitialBufferSize> punycode_output;
+  if (!url_canon::IDNToASCII(hostname_utf16.data(),
+                             hostname_utf16.length(),
+                             &punycode_output)) {
+    return false;
+  }
+
+  // |punycode_output| should now be ASCII; convert it to a std::string.
+  // (We could use UTF16ToASCII() instead, but that requires an extra string
+  // copy. Since ASCII is a subset of UTF8 the following is equivalent).
+  bool success = UTF16ToUTF8(punycode_output.data(),
+                             punycode_output.length(),
+                             hostname);
+  DCHECK(success);
+  DCHECK(IsStringASCII(*hostname));
+  return success;
+}
+
+// Wrapper for passing around IP address strings and IPAddressNumber objects.
+struct IPAddress {
+  IPAddress(const std::string& ip_string, const IPAddressNumber& ip_number)
+      : string_value(ip_string),
+        ip_address_number(ip_number) {
+  }
+
+  // Used for sorting IP addresses in ascending order in SortIpAddressList().
+  // IP6 addresses are placed ahead of IPv4 addresses.
+  bool operator<(const IPAddress& rhs) const {
+    const IPAddressNumber& ip1 = this->ip_address_number;
+    const IPAddressNumber& ip2 = rhs.ip_address_number;
+    if (ip1.size() != ip2.size())
+      return ip1.size() > ip2.size();  // IPv6 before IPv4.
+    DCHECK(ip1.size() == ip2.size());
+    return memcmp(&ip1[0], &ip2[0], ip1.size()) < 0;  // Ascending order.
+  }
+
+  std::string string_value;
+  IPAddressNumber ip_address_number;
+};
+
+// Handler for "sortIpAddressList(IpAddressList)". |ip_address_list| is a
+// semi-colon delimited string containing IP addresses.
+// |sorted_ip_address_list| is the resulting list of sorted semi-colon delimited
+// IP addresses or an empty string if unable to sort the IP address list.
+// Returns 'true' if the sorting was successful, and 'false' if the input was an
+// empty string, a string of separators (";" in this case), or if any of the IP
+// addresses in the input list failed to parse.
+bool SortIpAddressList(const std::string& ip_address_list,
+                       std::string* sorted_ip_address_list) {
+  sorted_ip_address_list->clear();
+
+  // Strip all whitespace (mimics IE behavior).
+  std::string cleaned_ip_address_list;
+  RemoveChars(ip_address_list, " \t", &cleaned_ip_address_list);
+  if (cleaned_ip_address_list.empty())
+    return false;
+
+  // Split-up IP addresses and store them in a vector.
+  std::vector<IPAddress> ip_vector;
+  IPAddressNumber ip_num;
+  StringTokenizer str_tok(cleaned_ip_address_list, ";");
+  while (str_tok.GetNext()) {
+    if (!ParseIPLiteralToNumber(str_tok.token(), &ip_num))
+      return false;
+    ip_vector.push_back(IPAddress(str_tok.token(), ip_num));
+  }
+
+  if (ip_vector.empty())  // Can happen if we have something like
+    return false;         // sortIpAddressList(";") or sortIpAddressList("; ;")
+
+  DCHECK(!ip_vector.empty());
+
+  // Sort lists according to ascending numeric value.
+  if (ip_vector.size() > 1)
+    std::stable_sort(ip_vector.begin(), ip_vector.end());
+
+  // Return a semi-colon delimited list of sorted addresses (IPv6 followed by
+  // IPv4).
+  for (size_t i = 0; i < ip_vector.size(); ++i) {
+    if (i > 0)
+      *sorted_ip_address_list += ";";
+    *sorted_ip_address_list += ip_vector[i].string_value;
+  }
+  return true;
+}
+
+// Handler for "isInNetEx(ip_address, ip_prefix)". |ip_address| is a string
+// containing an IPv4/IPv6 address, and |ip_prefix| is a string containg a
+// slash-delimited IP prefix with the top 'n' bits specified in the bit
+// field. This returns 'true' if the address is in the same subnet, and
+// 'false' otherwise. Also returns 'false' if the prefix is in an incorrect
+// format, or if an address and prefix of different types are used (e.g. IPv6
+// address and IPv4 prefix).
+bool IsInNetEx(const std::string& ip_address, const std::string& ip_prefix) {
+  IPAddressNumber address;
+  if (!ParseIPLiteralToNumber(ip_address, &address))
+    return false;
+
+  IPAddressNumber prefix;
+  size_t prefix_length_in_bits;
+  if (!ParseCIDRBlock(ip_prefix, &prefix, &prefix_length_in_bits))
+    return false;
+
+  // Both |address| and |prefix| must be of the same type (IPv4 or IPv6).
+  if (address.size() != prefix.size())
+    return false;
+
+  DCHECK((address.size() == 4 && prefix.size() == 4) ||
+         (address.size() == 16 && prefix.size() == 16));
+
+  return IPNumberMatchesPrefix(address, prefix, prefix_length_in_bits);
+}
+
+}  // namespace
+
+// ProxyResolverV8::Context ---------------------------------------------------
+
+class ProxyResolverV8::Context {
+ public:
+  explicit Context(ProxyResolverJSBindings* js_bindings)
+      : is_resolving_host_(false),
+        js_bindings_(js_bindings) {
+    DCHECK(js_bindings != NULL);
+  }
+
+  ~Context() {
+    v8::Locker locked;
+
+    v8_this_.Dispose();
+    v8_context_.Dispose();
+
+    // Run the V8 garbage collector. We do this to be sure the
+    // ExternalStringResource objects we allocated get properly disposed.
+    // Otherwise when running the unit-tests they may get leaked.
+    // See crbug.com/48145.
+    PurgeMemory();
+  }
+
+  int ResolveProxy(const GURL& query_url, ProxyInfo* results) {
+    v8::Locker locked;
+    v8::HandleScope scope;
+
+    v8::Context::Scope function_scope(v8_context_);
+
+    v8::Local<v8::Value> function;
+    if (!GetFindProxyForURL(&function)) {
+      js_bindings_->OnError(
+          -1, ASCIIToUTF16("FindProxyForURL() is undefined."));
+      return ERR_PAC_SCRIPT_FAILED;
+    }
+
+    v8::Handle<v8::Value> argv[] = {
+      ASCIIStringToV8String(query_url.spec()),
+      ASCIIStringToV8String(query_url.HostNoBrackets()),
+    };
+
+    v8::TryCatch try_catch;
+    v8::Local<v8::Value> ret = v8::Function::Cast(*function)->Call(
+        v8_context_->Global(), arraysize(argv), argv);
+
+    if (try_catch.HasCaught()) {
+      HandleError(try_catch.Message());
+      return ERR_PAC_SCRIPT_FAILED;
+    }
+
+    if (!ret->IsString()) {
+      js_bindings_->OnError(
+          -1, ASCIIToUTF16("FindProxyForURL() did not return a string."));
+      return ERR_PAC_SCRIPT_FAILED;
+    }
+
+    string16 ret_str = V8StringToUTF16(ret->ToString());
+
+    if (!IsStringASCII(ret_str)) {
+      // TODO(eroman): Rather than failing when a wide string is returned, we
+      //               could extend the parsing to handle IDNA hostnames by
+      //               converting them to ASCII punycode.
+      //               crbug.com/47234
+      string16 error_message =
+          ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string "
+                       "(crbug.com/47234): ") + ret_str;
+      js_bindings_->OnError(-1, error_message);
+      return ERR_PAC_SCRIPT_FAILED;
+    }
+
+    results->UsePacString(UTF16ToASCII(ret_str));
+    return OK;
+  }
+
+  int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) {
+    v8::Locker locked;
+    v8::HandleScope scope;
+
+    v8_this_ = v8::Persistent<v8::External>::New(v8::External::New(this));
+    v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+
+    // Attach the javascript bindings.
+    v8::Local<v8::FunctionTemplate> alert_template =
+        v8::FunctionTemplate::New(&AlertCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("alert"), alert_template);
+
+    v8::Local<v8::FunctionTemplate> my_ip_address_template =
+        v8::FunctionTemplate::New(&MyIpAddressCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("myIpAddress"),
+        my_ip_address_template);
+
+    v8::Local<v8::FunctionTemplate> dns_resolve_template =
+        v8::FunctionTemplate::New(&DnsResolveCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("dnsResolve"),
+        dns_resolve_template);
+
+    // Microsoft's PAC extensions:
+
+    v8::Local<v8::FunctionTemplate> dns_resolve_ex_template =
+        v8::FunctionTemplate::New(&DnsResolveExCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("dnsResolveEx"),
+                         dns_resolve_ex_template);
+
+    v8::Local<v8::FunctionTemplate> my_ip_address_ex_template =
+        v8::FunctionTemplate::New(&MyIpAddressExCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("myIpAddressEx"),
+                         my_ip_address_ex_template);
+
+    v8::Local<v8::FunctionTemplate> sort_ip_address_list_template =
+        v8::FunctionTemplate::New(&SortIpAddressListCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("sortIpAddressList"),
+                         sort_ip_address_list_template);
+
+    v8::Local<v8::FunctionTemplate> is_in_net_ex_template =
+        v8::FunctionTemplate::New(&IsInNetExCallback, v8_this_);
+    global_template->Set(ASCIILiteralToV8String("isInNetEx"),
+                         is_in_net_ex_template);
+
+    v8_context_ = v8::Context::New(NULL, global_template);
+
+    v8::Context::Scope ctx(v8_context_);
+
+    // Add the PAC utility functions to the environment.
+    // (This script should never fail, as it is a string literal!)
+    // Note that the two string literals are concatenated.
+    int rv = RunScript(
+        ASCIILiteralToV8String(
+            PROXY_RESOLVER_SCRIPT
+            PROXY_RESOLVER_SCRIPT_EX),
+        kPacUtilityResourceName);
+    if (rv != OK) {
+      NOTREACHED();
+      return rv;
+    }
+
+    // Add the user's PAC code to the environment.
+    rv = RunScript(ScriptDataToV8String(pac_script), kPacResourceName);
+    if (rv != OK)
+      return rv;
+
+    // At a minimum, the FindProxyForURL() function must be defined for this
+    // to be a legitimiate PAC script.
+    v8::Local<v8::Value> function;
+    if (!GetFindProxyForURL(&function)) {
+      js_bindings_->OnError(
+          -1, ASCIIToUTF16("FindProxyForURL() is undefined."));
+      return ERR_PAC_SCRIPT_FAILED;
+    }
+
+    return OK;
+  }
+
+  void SetCurrentRequestContext(ProxyResolverRequestContext* context) {
+    js_bindings_->set_current_request_context(context);
+  }
+
+  void PurgeMemory() {
+    v8::Locker locked;
+    v8::V8::LowMemoryNotification();
+  }
+
+  bool is_resolving_host() const {
+    base::AutoLock auto_lock(lock_);
+    return is_resolving_host_;
+  }
+
+ private:
+  class ScopedHostResolve {
+   public:
+    explicit ScopedHostResolve(Context* context)
+        : context_(context) {
+      context_->BeginHostResolve();
+    }
+
+    ~ScopedHostResolve() {
+      context_->EndHostResolve();
+    }
+
+   private:
+    Context* const context_;
+    DISALLOW_COPY_AND_ASSIGN(ScopedHostResolve);
+  };
+
+  void BeginHostResolve() {
+    base::AutoLock auto_lock(lock_);
+    DCHECK(!is_resolving_host_);
+    is_resolving_host_ = true;
+  }
+
+  void EndHostResolve() {
+    base::AutoLock auto_lock(lock_);
+    DCHECK(is_resolving_host_);
+    is_resolving_host_ = false;
+  }
+
+  bool GetFindProxyForURL(v8::Local<v8::Value>* function) {
+    *function = v8_context_->Global()->Get(
+        ASCIILiteralToV8String("FindProxyForURL"));
+    return (*function)->IsFunction();
+  }
+
+  // Handle an exception thrown by V8.
+  void HandleError(v8::Handle<v8::Message> message) {
+    if (message.IsEmpty())
+      return;
+
+    // Otherwise dispatch to the bindings.
+    int line_number = message->GetLineNumber();
+    string16 error_message;
+    V8ObjectToUTF16String(message->Get(), &error_message);
+    js_bindings_->OnError(line_number, error_message);
+  }
+
+  // Compiles and runs |script| in the current V8 context.
+  // Returns OK on success, otherwise an error code.
+  int RunScript(v8::Handle<v8::String> script, const char* script_name) {
+    v8::TryCatch try_catch;
+
+    // Compile the script.
+    v8::ScriptOrigin origin =
+        v8::ScriptOrigin(ASCIILiteralToV8String(script_name));
+    v8::Local<v8::Script> code = v8::Script::Compile(script, &origin);
+
+    // Execute.
+    if (!code.IsEmpty())
+      code->Run();
+
+    // Check for errors.
+    if (try_catch.HasCaught()) {
+      HandleError(try_catch.Message());
+      return ERR_PAC_SCRIPT_FAILED;
+    }
+
+    return OK;
+  }
+
+  // V8 callback for when "alert()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> AlertCallback(const v8::Arguments& args) {
+    Context* context =
+        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
+
+    // Like firefox we assume "undefined" if no argument was specified, and
+    // disregard any arguments beyond the first.
+    string16 message;
+    if (args.Length() == 0) {
+      message = ASCIIToUTF16("undefined");
+    } else {
+      if (!V8ObjectToUTF16String(args[0], &message))
+        return v8::Undefined();  // toString() threw an exception.
+    }
+
+    context->js_bindings_->Alert(message);
+    return v8::Undefined();
+  }
+
+  // V8 callback for when "myIpAddress()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> MyIpAddressCallback(const v8::Arguments& args) {
+    Context* context =
+        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
+
+    std::string result;
+    bool success;
+
+    {
+      v8::Unlocker unlocker;
+      ScopedHostResolve scoped_host_resolve(context);
+
+      // We shouldn't be called with any arguments, but will not complain if
+      // we are.
+      success = context->js_bindings_->MyIpAddress(&result);
+    }
+
+    if (!success)
+      return ASCIILiteralToV8String("127.0.0.1");
+    return ASCIIStringToV8String(result);
+  }
+
+  // V8 callback for when "myIpAddressEx()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> MyIpAddressExCallback(
+      const v8::Arguments& args) {
+    Context* context =
+        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
+
+    std::string ip_address_list;
+    bool success;
+
+    {
+      v8::Unlocker unlocker;
+      ScopedHostResolve scoped_host_resolve(context);
+
+      // We shouldn't be called with any arguments, but will not complain if
+      // we are.
+      success = context->js_bindings_->MyIpAddressEx(&ip_address_list);
+    }
+
+    if (!success)
+      ip_address_list = std::string();
+    return ASCIIStringToV8String(ip_address_list);
+  }
+
+  // V8 callback for when "dnsResolve()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> DnsResolveCallback(const v8::Arguments& args) {
+    Context* context =
+        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
+
+    // We need at least one string argument.
+    std::string hostname;
+    if (!GetHostnameArgument(args, &hostname))
+      return v8::Null();
+
+    std::string ip_address;
+    bool success;
+
+    {
+      v8::Unlocker unlocker;
+      ScopedHostResolve scoped_host_resolve(context);
+      success = context->js_bindings_->DnsResolve(hostname, &ip_address);
+    }
+
+    return success ? ASCIIStringToV8String(ip_address) : v8::Null();
+  }
+
+  // V8 callback for when "dnsResolveEx()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> DnsResolveExCallback(const v8::Arguments& args) {
+    Context* context =
+        static_cast<Context*>(v8::External::Cast(*args.Data())->Value());
+
+    // We need at least one string argument.
+    std::string hostname;
+    if (!GetHostnameArgument(args, &hostname))
+      return v8::Undefined();
+
+    std::string ip_address_list;
+    bool success;
+
+    {
+      v8::Unlocker unlocker;
+      ScopedHostResolve scoped_host_resolve(context);
+      success = context->js_bindings_->DnsResolveEx(hostname, &ip_address_list);
+    }
+
+    if (!success)
+      ip_address_list = std::string();
+
+    return ASCIIStringToV8String(ip_address_list);
+  }
+
+  // V8 callback for when "sortIpAddressList()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> SortIpAddressListCallback(
+      const v8::Arguments& args) {
+    // We need at least one string argument.
+    if (args.Length() == 0 || args[0].IsEmpty() || !args[0]->IsString())
+      return v8::Null();
+
+    std::string ip_address_list = V8StringToUTF8(args[0]->ToString());
+    if (!IsStringASCII(ip_address_list))
+      return v8::Null();
+    std::string sorted_ip_address_list;
+    bool success = SortIpAddressList(ip_address_list, &sorted_ip_address_list);
+    if (!success)
+      return v8::False();
+    return ASCIIStringToV8String(sorted_ip_address_list);
+  }
+
+  // V8 callback for when "isInNetEx()" is invoked by the PAC script.
+  static v8::Handle<v8::Value> IsInNetExCallback(const v8::Arguments& args) {
+    // We need at least 2 string arguments.
+    if (args.Length() < 2 || args[0].IsEmpty() || !args[0]->IsString() ||
+        args[1].IsEmpty() || !args[1]->IsString())
+      return v8::Null();
+
+    std::string ip_address = V8StringToUTF8(args[0]->ToString());
+    if (!IsStringASCII(ip_address))
+      return v8::False();
+    std::string ip_prefix = V8StringToUTF8(args[1]->ToString());
+    if (!IsStringASCII(ip_prefix))
+      return v8::False();
+    return IsInNetEx(ip_address, ip_prefix) ? v8::True() : v8::False();
+  }
+
+  mutable base::Lock lock_;
+  bool is_resolving_host_;
+  ProxyResolverJSBindings* js_bindings_;
+  v8::Persistent<v8::External> v8_this_;
+  v8::Persistent<v8::Context> v8_context_;
+};
+
+// ProxyResolverV8 ------------------------------------------------------------
+
+ProxyResolverV8::ProxyResolverV8(
+    ProxyResolverJSBindings* custom_js_bindings)
+    : ProxyResolver(true /*expects_pac_bytes*/),
+      js_bindings_(custom_js_bindings) {
+}
+
+ProxyResolverV8::~ProxyResolverV8() {}
+
+int ProxyResolverV8::GetProxyForURL(
+    const GURL& query_url, ProxyInfo* results,
+    const CompletionCallback& /*callback*/,
+    RequestHandle* /*request*/,
+    const BoundNetLog& net_log) {
+  // If the V8 instance has not been initialized (either because
+  // SetPacScript() wasn't called yet, or because it failed.
+  if (!context_.get())
+    return ERR_FAILED;
+
+  // Associate some short-lived context with this request. This context will be
+  // available to any of the javascript "bindings" that are subsequently invoked
+  // from the javascript.
+  //
+  // In particular, we create a HostCache to aggressively cache failed DNS
+  // resolves.
+  const unsigned kMaxCacheEntries = 50;
+  HostCache host_cache(kMaxCacheEntries);
+
+  ProxyResolverRequestContext request_context(&net_log, &host_cache);
+
+  // Otherwise call into V8.
+  context_->SetCurrentRequestContext(&request_context);
+  int rv = context_->ResolveProxy(query_url, results);
+  context_->SetCurrentRequestContext(NULL);
+
+  return rv;
+}
+
+void ProxyResolverV8::CancelRequest(RequestHandle request) {
+  // This is a synchronous ProxyResolver; no possibility for async requests.
+  NOTREACHED();
+}
+
+LoadState ProxyResolverV8::GetLoadState(RequestHandle request) const {
+  NOTREACHED();
+  return LOAD_STATE_IDLE;
+}
+
+LoadState ProxyResolverV8::GetLoadStateThreadSafe(RequestHandle request) const {
+  if (context_->is_resolving_host())
+    return LOAD_STATE_RESOLVING_HOST_IN_PROXY_SCRIPT;
+  return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
+}
+
+void ProxyResolverV8::CancelSetPacScript() {
+  NOTREACHED();
+}
+
+void ProxyResolverV8::PurgeMemory() {
+  context_->PurgeMemory();
+}
+
+void ProxyResolverV8::Shutdown() {
+  js_bindings_->Shutdown();
+}
+
+int ProxyResolverV8::SetPacScript(
+    const scoped_refptr<ProxyResolverScriptData>& script_data,
+    const CompletionCallback& /*callback*/) {
+  DCHECK(script_data.get());
+  context_.reset();
+  if (script_data->utf16().empty())
+    return ERR_PAC_SCRIPT_FAILED;
+
+  // Try parsing the PAC script.
+  scoped_ptr<Context> context(new Context(js_bindings_.get()));
+  int rv = context->InitV8(script_data);
+  if (rv == OK)
+    context_.reset(context.release());
+  return rv;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_v8.h b/src/net/proxy/proxy_resolver_v8.h
new file mode 100644
index 0000000..c00bb8a
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_v8.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_V8_H_
+#define NET_PROXY_PROXY_RESOLVER_V8_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/base/net_export.h"
+#include "net/proxy/proxy_resolver.h"
+
+namespace net {
+
+class ProxyResolverJSBindings;
+
+// Implementation of ProxyResolver that uses V8 to evaluate PAC scripts.
+//
+// ----------------------------------------------------------------------------
+// !!! Important note on threading model:
+// ----------------------------------------------------------------------------
+// There can be only one instance of V8 running at a time. To enforce this
+// constraint, ProxyResolverV8 holds a v8::Locker during execution. Therefore
+// it is OK to run multiple instances of ProxyResolverV8 on different threads,
+// since only one will be running inside V8 at a time.
+//
+// It is important that *ALL* instances of V8 in the process be using
+// v8::Locker. If not there can be race conditions between the non-locked V8
+// instances and the locked V8 instances used by ProxyResolverV8 (assuming they
+// run on different threads).
+//
+// This is the case with the V8 instance used by chromium's renderer -- it runs
+// on a different thread from ProxyResolver (renderer thread vs PAC thread),
+// and does not use locking since it expects to be alone.
+class NET_EXPORT_PRIVATE ProxyResolverV8 : public ProxyResolver {
+ public:
+  // Constructs a ProxyResolverV8 with custom bindings. ProxyResolverV8 takes
+  // ownership of |custom_js_bindings| and deletes it when ProxyResolverV8
+  // is destroyed.
+  explicit ProxyResolverV8(ProxyResolverJSBindings* custom_js_bindings);
+
+  virtual ~ProxyResolverV8();
+
+  ProxyResolverJSBindings* js_bindings() const { return js_bindings_.get(); }
+
+  // ProxyResolver implementation:
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const net::CompletionCallback& /*callback*/,
+                             RequestHandle* /*request*/,
+                             const BoundNetLog& net_log) OVERRIDE;
+  virtual void CancelRequest(RequestHandle request) OVERRIDE;
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE;
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE;
+  virtual void CancelSetPacScript() OVERRIDE;
+  virtual void PurgeMemory() OVERRIDE;
+  virtual void Shutdown() OVERRIDE;
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const net::CompletionCallback& /*callback*/) OVERRIDE;
+
+ private:
+  // Context holds the Javascript state for the most recently loaded PAC
+  // script. It corresponds with the data from the last call to
+  // SetPacScript().
+  class Context;
+  scoped_ptr<Context> context_;
+
+  scoped_ptr<ProxyResolverJSBindings> js_bindings_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyResolverV8);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_V8_H_
diff --git a/src/net/proxy/proxy_resolver_v8_unittest.cc b/src/net/proxy/proxy_resolver_v8_unittest.cc
new file mode 100644
index 0000000..b93d4f3
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_v8_unittest.cc
@@ -0,0 +1,571 @@
+// Copyright (c) 2012 The Chromium Authors. 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/compiler_specific.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_util.h"
+#include "base/stringprintf.h"
+#include "base/utf_string_conversions.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log_unittest.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_resolver_js_bindings.h"
+#include "net/proxy/proxy_resolver_v8.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+// Javascript bindings for ProxyResolverV8, which returns mock values.
+// Each time one of the bindings is called into, we push the input into a
+// list, for later verification.
+class MockJSBindings : public ProxyResolverJSBindings {
+ public:
+  MockJSBindings() : my_ip_address_count(0), my_ip_address_ex_count(0) {}
+
+  virtual void Alert(const string16& message) OVERRIDE {
+    VLOG(1) << "PAC-alert: " << message;  // Helpful when debugging.
+    alerts.push_back(UTF16ToUTF8(message));
+  }
+
+  virtual bool MyIpAddress(std::string* ip_address) OVERRIDE {
+    my_ip_address_count++;
+    *ip_address = my_ip_address_result;
+    return !my_ip_address_result.empty();
+  }
+
+  virtual bool MyIpAddressEx(std::string* ip_address_list) OVERRIDE {
+    my_ip_address_ex_count++;
+    *ip_address_list = my_ip_address_ex_result;
+    return !my_ip_address_ex_result.empty();
+  }
+
+  virtual bool DnsResolve(const std::string& host, std::string* ip_address)
+      OVERRIDE {
+    dns_resolves.push_back(host);
+    *ip_address = dns_resolve_result;
+    return !dns_resolve_result.empty();
+  }
+
+  virtual bool DnsResolveEx(const std::string& host,
+                            std::string* ip_address_list) OVERRIDE {
+    dns_resolves_ex.push_back(host);
+    *ip_address_list = dns_resolve_ex_result;
+    return !dns_resolve_ex_result.empty();
+  }
+
+  virtual void OnError(int line_number, const string16& message) OVERRIDE {
+    // Helpful when debugging.
+    VLOG(1) << "PAC-error: [" << line_number << "] " << message;
+
+    errors.push_back(UTF16ToUTF8(message));
+    errors_line_number.push_back(line_number);
+  }
+
+  virtual void Shutdown() OVERRIDE {}
+
+  // Mock values to return.
+  std::string my_ip_address_result;
+  std::string my_ip_address_ex_result;
+  std::string dns_resolve_result;
+  std::string dns_resolve_ex_result;
+
+  // Inputs we got called with.
+  std::vector<std::string> alerts;
+  std::vector<std::string> errors;
+  std::vector<int> errors_line_number;
+  std::vector<std::string> dns_resolves;
+  std::vector<std::string> dns_resolves_ex;
+  int my_ip_address_count;
+  int my_ip_address_ex_count;
+};
+
+// This is the same as ProxyResolverV8, but it uses mock bindings in place of
+// the default bindings, and has a helper function to load PAC scripts from
+// disk.
+class ProxyResolverV8WithMockBindings : public ProxyResolverV8 {
+ public:
+  ProxyResolverV8WithMockBindings() : ProxyResolverV8(new MockJSBindings()) {}
+
+  MockJSBindings* mock_js_bindings() const {
+    return reinterpret_cast<MockJSBindings*>(js_bindings());
+  }
+
+  // Initialize with the PAC script data at |filename|.
+  int SetPacScriptFromDisk(const char* filename) {
+    FilePath path;
+    PathService::Get(base::DIR_SOURCE_ROOT, &path);
+    path = path.AppendASCII("net");
+    path = path.AppendASCII("data");
+    path = path.AppendASCII("proxy_resolver_v8_unittest");
+    path = path.AppendASCII(filename);
+
+    // Try to read the file from disk.
+    std::string file_contents;
+    bool ok = file_util::ReadFileToString(path, &file_contents);
+
+    // If we can't load the file from disk, something is misconfigured.
+    if (!ok) {
+      LOG(ERROR) << "Failed to read file: " << path.value();
+      return ERR_UNEXPECTED;
+    }
+
+    // Load the PAC script into the ProxyResolver.
+    return SetPacScript(ProxyResolverScriptData::FromUTF8(file_contents),
+                        CompletionCallback());
+  }
+};
+
+// Doesn't really matter what these values are for many of the tests.
+const GURL kQueryUrl("http://www.google.com");
+const GURL kPacUrl;
+
+
+TEST(ProxyResolverV8Test, Direct) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("direct.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  CapturingBoundNetLog log;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, log.bound());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_TRUE(proxy_info.is_direct());
+
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+
+  net::CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+  // No bindings were called, so no log entries.
+  EXPECT_EQ(0u, entries.size());
+}
+
+TEST(ProxyResolverV8Test, ReturnEmptyString) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("return_empty_string.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_TRUE(proxy_info.is_direct());
+
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+}
+
+TEST(ProxyResolverV8Test, Basic) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("passthrough.js");
+  EXPECT_EQ(OK, result);
+
+  // The "FindProxyForURL" of this PAC script simply concatenates all of the
+  // arguments into a pseudo-host. The purpose of this test is to verify that
+  // the correct arguments are being passed to FindProxyForURL().
+  {
+    ProxyInfo proxy_info;
+    result = resolver.GetProxyForURL(GURL("http://query.com/path"), &proxy_info,
+                                     CompletionCallback(), NULL, BoundNetLog());
+    EXPECT_EQ(OK, result);
+    EXPECT_EQ("http.query.com.path.query.com:80",
+              proxy_info.proxy_server().ToURI());
+  }
+  {
+    ProxyInfo proxy_info;
+    int result = resolver.GetProxyForURL(
+        GURL("ftp://query.com:90/path"), &proxy_info, CompletionCallback(),
+        NULL, BoundNetLog());
+    EXPECT_EQ(OK, result);
+    // Note that FindProxyForURL(url, host) does not expect |host| to contain
+    // the port number.
+    EXPECT_EQ("ftp.query.com.90.path.query.com:80",
+              proxy_info.proxy_server().ToURI());
+
+    EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+    EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+  }
+
+  // We call this so we'll have code coverage of the function and valgrind will
+  // make sure nothing bad happens.
+  //
+  // NOTE: This is here instead of in its own test so that we'll be calling it
+  // after having done something, in hopes it won't be a no-op.
+  resolver.PurgeMemory();
+}
+
+TEST(ProxyResolverV8Test, BadReturnType) {
+  // These are the filenames of PAC scripts which each return a non-string
+  // types for FindProxyForURL(). They should all fail with
+  // ERR_PAC_SCRIPT_FAILED.
+  static const char* const filenames[] = {
+      "return_undefined.js",
+      "return_integer.js",
+      "return_function.js",
+      "return_object.js",
+      // TODO(eroman): Should 'null' be considered equivalent to "DIRECT" ?
+      "return_null.js"
+  };
+
+  for (size_t i = 0; i < arraysize(filenames); ++i) {
+    ProxyResolverV8WithMockBindings resolver;
+    int result = resolver.SetPacScriptFromDisk(filenames[i]);
+    EXPECT_EQ(OK, result);
+
+    ProxyInfo proxy_info;
+    result = resolver.GetProxyForURL(
+        kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+    EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
+
+    MockJSBindings* bindings = resolver.mock_js_bindings();
+    EXPECT_EQ(0U, bindings->alerts.size());
+    ASSERT_EQ(1U, bindings->errors.size());
+    EXPECT_EQ("FindProxyForURL() did not return a string.",
+              bindings->errors[0]);
+    EXPECT_EQ(-1, bindings->errors_line_number[0]);
+  }
+}
+
+// Try using a PAC script which defines no "FindProxyForURL" function.
+TEST(ProxyResolverV8Test, NoEntryPoint) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("no_entrypoint.js");
+  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(ERR_FAILED, result);
+}
+
+// Try loading a malformed PAC script.
+TEST(ProxyResolverV8Test, ParseError) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("missing_close_brace.js");
+  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(ERR_FAILED, result);
+
+  MockJSBindings* bindings = resolver.mock_js_bindings();
+  EXPECT_EQ(0U, bindings->alerts.size());
+
+  // We get one error during compilation.
+  ASSERT_EQ(1U, bindings->errors.size());
+
+  EXPECT_EQ("Uncaught SyntaxError: Unexpected end of input",
+            bindings->errors[0]);
+  EXPECT_EQ(0, bindings->errors_line_number[0]);
+}
+
+// Run a PAC script several times, which has side-effects.
+TEST(ProxyResolverV8Test, SideEffects) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("side_effects.js");
+
+  // The PAC script increments a counter each time we invoke it.
+  for (int i = 0; i < 3; ++i) {
+    ProxyInfo proxy_info;
+    result = resolver.GetProxyForURL(
+        kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+    EXPECT_EQ(OK, result);
+    EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
+              proxy_info.proxy_server().ToURI());
+  }
+
+  // Reload the script -- the javascript environment should be reset, hence
+  // the counter starts over.
+  result = resolver.SetPacScriptFromDisk("side_effects.js");
+  EXPECT_EQ(OK, result);
+
+  for (int i = 0; i < 3; ++i) {
+    ProxyInfo proxy_info;
+    result = resolver.GetProxyForURL(
+        kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+    EXPECT_EQ(OK, result);
+    EXPECT_EQ(base::StringPrintf("sideffect_%d:80", i),
+              proxy_info.proxy_server().ToURI());
+  }
+}
+
+// Execute a PAC script which throws an exception in FindProxyForURL.
+TEST(ProxyResolverV8Test, UnhandledException) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("unhandled_exception.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
+
+  MockJSBindings* bindings = resolver.mock_js_bindings();
+  EXPECT_EQ(0U, bindings->alerts.size());
+  ASSERT_EQ(1U, bindings->errors.size());
+  EXPECT_EQ("Uncaught ReferenceError: undefined_variable is not defined",
+            bindings->errors[0]);
+  EXPECT_EQ(3, bindings->errors_line_number[0]);
+}
+
+TEST(ProxyResolverV8Test, ReturnUnicode) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("return_unicode.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  // The result from this resolve was unparseable, because it
+  // wasn't ASCII.
+  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, result);
+}
+
+// Test the PAC library functions that we expose in the JS environment.
+TEST(ProxyResolverV8Test, JavascriptLibrary) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("pac_library_unittest.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  // If the javascript side of this unit-test fails, it will throw a javascript
+  // exception. Otherwise it will return "PROXY success:80".
+  EXPECT_EQ(OK, result);
+  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
+
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+}
+
+// Try resolving when SetPacScriptByData() has not been called.
+TEST(ProxyResolverV8Test, NoSetPacScript) {
+  ProxyResolverV8WithMockBindings resolver;
+
+  ProxyInfo proxy_info;
+
+  // Resolve should fail, as we are not yet initialized with a script.
+  int result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_FAILED, result);
+
+  // Initialize it.
+  result = resolver.SetPacScriptFromDisk("direct.js");
+  EXPECT_EQ(OK, result);
+
+  // Resolve should now succeed.
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, result);
+
+  // Clear it, by initializing with an empty string.
+  resolver.SetPacScript(
+      ProxyResolverScriptData::FromUTF16(string16()), CompletionCallback());
+
+  // Resolve should fail again now.
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_FAILED, result);
+
+  // Load a good script once more.
+  result = resolver.SetPacScriptFromDisk("direct.js");
+  EXPECT_EQ(OK, result);
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, result);
+
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->alerts.size());
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+}
+
+// Test marshalling/un-marshalling of values between C++/V8.
+TEST(ProxyResolverV8Test, V8Bindings) {
+  ProxyResolverV8WithMockBindings resolver;
+  MockJSBindings* bindings = resolver.mock_js_bindings();
+  bindings->dns_resolve_result = "127.0.0.1";
+  int result = resolver.SetPacScriptFromDisk("bindings.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_TRUE(proxy_info.is_direct());
+
+  EXPECT_EQ(0U, resolver.mock_js_bindings()->errors.size());
+
+  // Alert was called 5 times.
+  ASSERT_EQ(5U, bindings->alerts.size());
+  EXPECT_EQ("undefined", bindings->alerts[0]);
+  EXPECT_EQ("null", bindings->alerts[1]);
+  EXPECT_EQ("undefined", bindings->alerts[2]);
+  EXPECT_EQ("[object Object]", bindings->alerts[3]);
+  EXPECT_EQ("exception from calling toString()", bindings->alerts[4]);
+
+  // DnsResolve was called 8 times, however only 2 of those were string
+  // parameters. (so 6 of them failed immediately).
+  ASSERT_EQ(2U, bindings->dns_resolves.size());
+  EXPECT_EQ("", bindings->dns_resolves[0]);
+  EXPECT_EQ("arg1", bindings->dns_resolves[1]);
+
+  // MyIpAddress was called two times.
+  EXPECT_EQ(2, bindings->my_ip_address_count);
+
+  // MyIpAddressEx was called once.
+  EXPECT_EQ(1, bindings->my_ip_address_ex_count);
+
+  // DnsResolveEx was called 2 times.
+  ASSERT_EQ(2U, bindings->dns_resolves_ex.size());
+  EXPECT_EQ("is_resolvable", bindings->dns_resolves_ex[0]);
+  EXPECT_EQ("foobar", bindings->dns_resolves_ex[1]);
+}
+
+// Test calling a binding (myIpAddress()) from the script's global scope.
+// http://crbug.com/40026
+TEST(ProxyResolverV8Test, BindingCalledDuringInitialization) {
+  ProxyResolverV8WithMockBindings resolver;
+
+  int result = resolver.SetPacScriptFromDisk("binding_from_global.js");
+  EXPECT_EQ(OK, result);
+
+  MockJSBindings* bindings = resolver.mock_js_bindings();
+
+  // myIpAddress() got called during initialization of the script.
+  EXPECT_EQ(1, bindings->my_ip_address_count);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_FALSE(proxy_info.is_direct());
+  EXPECT_EQ("127.0.0.1:80", proxy_info.proxy_server().ToURI());
+
+  // Check that no other bindings were called.
+  EXPECT_EQ(0U, bindings->errors.size());
+  ASSERT_EQ(0U, bindings->alerts.size());
+  ASSERT_EQ(0U, bindings->dns_resolves.size());
+  EXPECT_EQ(0, bindings->my_ip_address_ex_count);
+  ASSERT_EQ(0U, bindings->dns_resolves_ex.size());
+}
+
+// Try loading a PAC script that ends with a comment and has no terminal
+// newline. This should not cause problems with the PAC utility functions
+// that we add to the script's environment.
+// http://crbug.com/22864
+TEST(ProxyResolverV8Test, EndsWithCommentNoNewline) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("ends_with_comment.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_FALSE(proxy_info.is_direct());
+  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
+}
+
+// Try loading a PAC script that ends with a statement and has no terminal
+// newline. This should not cause problems with the PAC utility functions
+// that we add to the script's environment.
+// http://crbug.com/22864
+TEST(ProxyResolverV8Test, EndsWithStatementNoNewline) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk(
+      "ends_with_statement_no_semicolon.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_FALSE(proxy_info.is_direct());
+  EXPECT_EQ("success:3", proxy_info.proxy_server().ToURI());
+}
+
+// Test the return values from myIpAddress(), myIpAddressEx(), dnsResolve(),
+// dnsResolveEx(), isResolvable(), isResolvableEx(), when the the binding
+// returns empty string (failure). This simulates the return values from
+// those functions when the underlying DNS resolution fails.
+TEST(ProxyResolverV8Test, DNSResolutionFailure) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("dns_fail.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_FALSE(proxy_info.is_direct());
+  EXPECT_EQ("success:80", proxy_info.proxy_server().ToURI());
+}
+
+TEST(ProxyResolverV8Test, DNSResolutionOfInternationDomainName) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("international_domain_names.js");
+  EXPECT_EQ(OK, result);
+
+  // Execute FindProxyForURL().
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      kQueryUrl, &proxy_info, CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_TRUE(proxy_info.is_direct());
+
+  // Check that the international domain name was converted to punycode
+  // before passing it onto the bindings layer.
+  MockJSBindings* bindings = resolver.mock_js_bindings();
+
+  ASSERT_EQ(1u, bindings->dns_resolves.size());
+  EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves[0]);
+
+  ASSERT_EQ(1u, bindings->dns_resolves_ex.size());
+  EXPECT_EQ("xn--bcher-kva.ch", bindings->dns_resolves_ex[0]);
+}
+
+// Test that when resolving a URL which contains an IPv6 string literal, the
+// brackets are removed from the host before passing it down to the PAC script.
+// If we don't do this, then subsequent calls to dnsResolveEx(host) will be
+// doomed to fail since it won't correspond with a valid name.
+TEST(ProxyResolverV8Test, IPv6HostnamesNotBracketed) {
+  ProxyResolverV8WithMockBindings resolver;
+  int result = resolver.SetPacScriptFromDisk("resolve_host.js");
+  EXPECT_EQ(OK, result);
+
+  ProxyInfo proxy_info;
+  result = resolver.GetProxyForURL(
+      GURL("http://[abcd::efff]:99/watsupdawg"), &proxy_info,
+      CompletionCallback(), NULL, BoundNetLog());
+
+  EXPECT_EQ(OK, result);
+  EXPECT_TRUE(proxy_info.is_direct());
+
+  // We called dnsResolveEx() exactly once, by passing through the "host"
+  // argument to FindProxyForURL(). The brackets should have been stripped.
+  ASSERT_EQ(1U, resolver.mock_js_bindings()->dns_resolves_ex.size());
+  EXPECT_EQ("abcd::efff", resolver.mock_js_bindings()->dns_resolves_ex[0]);
+}
+
+}  // namespace
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_winhttp.cc b/src/net/proxy/proxy_resolver_winhttp.cc
new file mode 100644
index 0000000..1e14fbb
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_winhttp.cc
@@ -0,0 +1,178 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/proxy_resolver_winhttp.h"
+
+#include <windows.h>
+#include <winhttp.h>
+
+#include "base/metrics/histogram.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_info.h"
+
+#pragma comment(lib, "winhttp.lib")
+
+using base::TimeDelta;
+using base::TimeTicks;
+
+namespace net {
+
+static void FreeInfo(WINHTTP_PROXY_INFO* info) {
+  if (info->lpszProxy)
+    GlobalFree(info->lpszProxy);
+  if (info->lpszProxyBypass)
+    GlobalFree(info->lpszProxyBypass);
+}
+
+ProxyResolverWinHttp::ProxyResolverWinHttp()
+    : ProxyResolver(false /*expects_pac_bytes*/), session_handle_(NULL) {
+}
+
+ProxyResolverWinHttp::~ProxyResolverWinHttp() {
+  CloseWinHttpSession();
+}
+
+int ProxyResolverWinHttp::GetProxyForURL(const GURL& query_url,
+                                         ProxyInfo* results,
+                                         const CompletionCallback& /*callback*/,
+                                         RequestHandle* /*request*/,
+                                         const BoundNetLog& /*net_log*/) {
+  // If we don't have a WinHTTP session, then create a new one.
+  if (!session_handle_ && !OpenWinHttpSession())
+    return ERR_FAILED;
+
+  // If we have been given an empty PAC url, then use auto-detection.
+  //
+  // NOTE: We just use DNS-based auto-detection here like Firefox.  We do this
+  // to avoid WinHTTP's auto-detection code, which while more featureful (it
+  // supports DHCP based auto-detection) also appears to have issues.
+  //
+  WINHTTP_AUTOPROXY_OPTIONS options = {0};
+  options.fAutoLogonIfChallenged = FALSE;
+  options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
+  std::wstring pac_url_wide = ASCIIToWide(pac_url_.spec());
+  options.lpszAutoConfigUrl = pac_url_wide.c_str();
+
+  WINHTTP_PROXY_INFO info = {0};
+  DCHECK(session_handle_);
+
+  // Per http://msdn.microsoft.com/en-us/library/aa383153(VS.85).aspx, it is
+  // necessary to first try resolving with fAutoLogonIfChallenged set to false.
+  // Otherwise, we fail over to trying it with a value of true.  This way we
+  // get good performance in the case where WinHTTP uses an out-of-process
+  // resolver.  This is important for Vista and Win2k3.
+  BOOL ok = WinHttpGetProxyForUrl(
+      session_handle_, ASCIIToWide(query_url.spec()).c_str(), &options, &info);
+  if (!ok) {
+    if (ERROR_WINHTTP_LOGIN_FAILURE == GetLastError()) {
+      options.fAutoLogonIfChallenged = TRUE;
+      ok = WinHttpGetProxyForUrl(
+          session_handle_, ASCIIToWide(query_url.spec()).c_str(),
+          &options, &info);
+    }
+    if (!ok) {
+      DWORD error = GetLastError();
+      // If we got here because of RPC timeout during out of process PAC
+      // resolution, no further requests on this session are going to work.
+      if (ERROR_WINHTTP_TIMEOUT == error ||
+          ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR == error) {
+        CloseWinHttpSession();
+      }
+      return ERR_FAILED;  // TODO(darin): Bug 1189288: translate error code.
+    }
+  }
+
+  int rv = OK;
+
+  switch (info.dwAccessType) {
+    case WINHTTP_ACCESS_TYPE_NO_PROXY:
+      results->UseDirect();
+      break;
+    case WINHTTP_ACCESS_TYPE_NAMED_PROXY:
+      // According to MSDN:
+      //
+      // The proxy server list contains one or more of the following strings
+      // separated by semicolons or whitespace.
+      //
+      // ([<scheme>=][<scheme>"://"]<server>[":"<port>])
+      //
+      // Based on this description, ProxyInfo::UseNamedProxy() isn't
+      // going to handle all the variations (in particular <scheme>=).
+      //
+      // However in practice, it seems that WinHTTP is simply returning
+      // things like "foopy1:80;foopy2:80". It strips out the non-HTTP
+      // proxy types, and stops the list when PAC encounters a "DIRECT".
+      // So UseNamedProxy() should work OK.
+      results->UseNamedProxy(WideToASCII(info.lpszProxy));
+      break;
+    default:
+      NOTREACHED();
+      rv = ERR_FAILED;
+  }
+
+  FreeInfo(&info);
+  return rv;
+}
+
+void ProxyResolverWinHttp::CancelRequest(RequestHandle request) {
+  // This is a synchronous ProxyResolver; no possibility for async requests.
+  NOTREACHED();
+}
+
+LoadState ProxyResolverWinHttp::GetLoadState(RequestHandle request) const {
+  NOTREACHED();
+  return LOAD_STATE_IDLE;
+}
+
+LoadState ProxyResolverWinHttp::GetLoadStateThreadSafe(
+    RequestHandle request) const {
+  return LOAD_STATE_IDLE;
+}
+
+void ProxyResolverWinHttp::CancelSetPacScript() {
+  NOTREACHED();
+}
+
+int ProxyResolverWinHttp::SetPacScript(
+    const scoped_refptr<ProxyResolverScriptData>& script_data,
+    const CompletionCallback& /*callback*/) {
+  if (script_data->type() == ProxyResolverScriptData::TYPE_AUTO_DETECT) {
+    pac_url_ = GURL("http://wpad/wpad.dat");
+  } else {
+    pac_url_ = script_data->url();
+  }
+  return OK;
+}
+
+bool ProxyResolverWinHttp::OpenWinHttpSession() {
+  DCHECK(!session_handle_);
+  session_handle_ = WinHttpOpen(NULL,
+                                WINHTTP_ACCESS_TYPE_NO_PROXY,
+                                WINHTTP_NO_PROXY_NAME,
+                                WINHTTP_NO_PROXY_BYPASS,
+                                0);
+  if (!session_handle_)
+    return false;
+
+  // Since this session handle will never be used for WinHTTP connections,
+  // these timeouts don't really mean much individually.  However, WinHTTP's
+  // out of process PAC resolution will use a combined (sum of all timeouts)
+  // value to wait for an RPC reply.
+  BOOL rv = WinHttpSetTimeouts(session_handle_, 10000, 10000, 5000, 5000);
+  DCHECK(rv);
+
+  return true;
+}
+
+void ProxyResolverWinHttp::CloseWinHttpSession() {
+  if (session_handle_) {
+    WinHttpCloseHandle(session_handle_);
+    session_handle_ = NULL;
+  }
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_resolver_winhttp.h b/src/net/proxy/proxy_resolver_winhttp.h
new file mode 100644
index 0000000..e92827a
--- /dev/null
+++ b/src/net/proxy/proxy_resolver_winhttp.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_RESOLVER_WINHTTP_H_
+#define NET_PROXY_PROXY_RESOLVER_WINHTTP_H_
+
+#include "base/compiler_specific.h"
+#include "googleurl/src/gurl.h"
+#include "net/proxy/proxy_resolver.h"
+
+typedef void* HINTERNET;  // From winhttp.h
+
+namespace net {
+
+// An implementation of ProxyResolver that uses WinHTTP and the system
+// proxy settings.
+class NET_EXPORT_PRIVATE ProxyResolverWinHttp : public ProxyResolver {
+ public:
+  ProxyResolverWinHttp();
+  virtual ~ProxyResolverWinHttp();
+
+  // ProxyResolver implementation:
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const net::CompletionCallback& /*callback*/,
+                             RequestHandle* /*request*/,
+                             const BoundNetLog& /*net_log*/) OVERRIDE;
+  virtual void CancelRequest(RequestHandle request) OVERRIDE;
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE;
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE;
+
+  virtual void CancelSetPacScript() OVERRIDE;
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const net::CompletionCallback& /*callback*/) OVERRIDE;
+
+ private:
+  bool OpenWinHttpSession();
+  void CloseWinHttpSession();
+
+  // Proxy configuration is cached on the session handle.
+  HINTERNET session_handle_;
+
+  GURL pac_url_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyResolverWinHttp);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RESOLVER_WINHTTP_H_
diff --git a/src/net/proxy/proxy_retry_info.h b/src/net/proxy/proxy_retry_info.h
new file mode 100644
index 0000000..c5ac782
--- /dev/null
+++ b/src/net/proxy/proxy_retry_info.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2006-2008 The Chromium Authors. 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_PROXY_PROXY_RETRY_INFO_H_
+#define NET_PROXY_PROXY_RETRY_INFO_H_
+
+#include <map>
+
+#include "base/time.h"
+
+namespace net {
+
+// Contains the information about when to retry a proxy server.
+struct ProxyRetryInfo {
+  // We should not retry until this time.
+  base::TimeTicks bad_until;
+
+  // This is the current delay. If the proxy is still bad, we need to increase
+  // this delay.
+  base::TimeDelta current_delay;
+};
+
+// Map of proxy servers with the associated RetryInfo structures.
+// The key is a proxy URI string [<scheme>"://"]<host>":"<port>.
+typedef std::map<std::string, ProxyRetryInfo> ProxyRetryInfoMap;
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_RETRY_INFO_H_
diff --git a/src/net/proxy/proxy_script_decider.cc b/src/net/proxy/proxy_script_decider.cc
new file mode 100644
index 0000000..21e3ae0
--- /dev/null
+++ b/src/net/proxy/proxy_script_decider.cc
@@ -0,0 +1,414 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_script_decider.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/compiler_specific.h"
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/dhcp_proxy_script_fetcher.h"
+#include "net/proxy/dhcp_proxy_script_fetcher_factory.h"
+#include "net/proxy/proxy_script_fetcher.h"
+
+namespace net {
+
+namespace {
+
+bool LooksLikePacScript(const string16& script) {
+  // Note: this is only an approximation! It may not always work correctly,
+  // however it is very likely that legitimate scripts have this exact string,
+  // since they must minimally define a function of this name. Conversely, a
+  // file not containing the string is not likely to be a PAC script.
+  //
+  // An exact test would have to load the script in a javascript evaluator.
+  return script.find(ASCIIToUTF16("FindProxyForURL")) != string16::npos;
+}
+
+}
+
+// This is the hard-coded location used by the DNS portion of web proxy
+// auto-discovery.
+//
+// Note that we not use DNS devolution to find the WPAD host, since that could
+// be dangerous should our top level domain registry  become out of date.
+//
+// Instead we directly resolve "wpad", and let the operating system apply the
+// DNS suffix search paths. This is the same approach taken by Firefox, and
+// compatibility hasn't been an issue.
+//
+// For more details, also check out this comment:
+// http://code.google.com/p/chromium/issues/detail?id=18575#c20
+static const char kWpadUrl[] = "http://wpad/wpad.dat";
+
+Value* ProxyScriptDecider::PacSource::NetLogCallback(
+    const GURL* effective_pac_url,
+    NetLog::LogLevel /* log_level */) const {
+  DictionaryValue* dict = new DictionaryValue();
+  std::string source;
+  switch (type) {
+    case PacSource::WPAD_DHCP:
+      source = "WPAD DHCP";
+      break;
+    case PacSource::WPAD_DNS:
+      source = "WPAD DNS: ";
+      source += effective_pac_url->possibly_invalid_spec();
+      break;
+    case PacSource::CUSTOM:
+      source = "Custom PAC URL: ";
+      source += effective_pac_url->possibly_invalid_spec();
+      break;
+  }
+  dict->SetString("source", source);
+  return dict;
+}
+
+ProxyScriptDecider::ProxyScriptDecider(
+    ProxyScriptFetcher* proxy_script_fetcher,
+    DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+    NetLog* net_log)
+    : resolver_(NULL),
+      proxy_script_fetcher_(proxy_script_fetcher),
+      dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher),
+      current_pac_source_index_(0u),
+      pac_mandatory_(false),
+      next_state_(STATE_NONE),
+      net_log_(BoundNetLog::Make(
+          net_log, NetLog::SOURCE_PROXY_SCRIPT_DECIDER)),
+      fetch_pac_bytes_(false) {
+}
+
+ProxyScriptDecider::~ProxyScriptDecider() {
+  if (next_state_ != STATE_NONE)
+    Cancel();
+}
+
+int ProxyScriptDecider::Start(
+    const ProxyConfig& config, const base::TimeDelta wait_delay,
+    bool fetch_pac_bytes, const CompletionCallback& callback) {
+  DCHECK_EQ(STATE_NONE, next_state_);
+  DCHECK(!callback.is_null());
+  DCHECK(config.HasAutomaticSettings());
+
+  net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER);
+
+  fetch_pac_bytes_ = fetch_pac_bytes;
+
+  // Save the |wait_delay| as a non-negative value.
+  wait_delay_ = wait_delay;
+  if (wait_delay_ < base::TimeDelta())
+    wait_delay_ = base::TimeDelta();
+
+  pac_mandatory_ = config.pac_mandatory();
+
+  pac_sources_ = BuildPacSourcesFallbackList(config);
+  DCHECK(!pac_sources_.empty());
+
+  next_state_ = STATE_WAIT;
+
+  int rv = DoLoop(OK);
+  if (rv == ERR_IO_PENDING)
+    callback_ = callback;
+  else
+    DidComplete();
+
+  return rv;
+}
+
+const ProxyConfig& ProxyScriptDecider::effective_config() const {
+  DCHECK_EQ(STATE_NONE, next_state_);
+  return effective_config_;
+}
+
+// TODO(eroman): Return a const-pointer.
+ProxyResolverScriptData* ProxyScriptDecider::script_data() const {
+  DCHECK_EQ(STATE_NONE, next_state_);
+  return script_data_.get();
+}
+
+// Initialize the fallback rules.
+// (1) WPAD (DHCP).
+// (2) WPAD (DNS).
+// (3) Custom PAC URL.
+ProxyScriptDecider::PacSourceList ProxyScriptDecider::
+    BuildPacSourcesFallbackList(
+    const ProxyConfig& config) const {
+  PacSourceList pac_sources;
+  if (config.auto_detect()) {
+    pac_sources.push_back(PacSource(PacSource::WPAD_DHCP, GURL()));
+    pac_sources.push_back(PacSource(PacSource::WPAD_DNS, GURL()));
+  }
+  if (config.has_pac_url())
+    pac_sources.push_back(PacSource(PacSource::CUSTOM, config.pac_url()));
+  return pac_sources;
+}
+
+void ProxyScriptDecider::OnIOCompletion(int result) {
+  DCHECK_NE(STATE_NONE, next_state_);
+  int rv = DoLoop(result);
+  if (rv != ERR_IO_PENDING) {
+    DidComplete();
+    DoCallback(rv);
+  }
+}
+
+int ProxyScriptDecider::DoLoop(int result) {
+  DCHECK_NE(next_state_, STATE_NONE);
+  int rv = result;
+  do {
+    State state = next_state_;
+    next_state_ = STATE_NONE;
+    switch (state) {
+      case STATE_WAIT:
+        DCHECK_EQ(OK, rv);
+        rv = DoWait();
+        break;
+      case STATE_WAIT_COMPLETE:
+        rv = DoWaitComplete(rv);
+        break;
+      case STATE_FETCH_PAC_SCRIPT:
+        DCHECK_EQ(OK, rv);
+        rv = DoFetchPacScript();
+        break;
+      case STATE_FETCH_PAC_SCRIPT_COMPLETE:
+        rv = DoFetchPacScriptComplete(rv);
+        break;
+      case STATE_VERIFY_PAC_SCRIPT:
+        DCHECK_EQ(OK, rv);
+        rv = DoVerifyPacScript();
+        break;
+      case STATE_VERIFY_PAC_SCRIPT_COMPLETE:
+        rv = DoVerifyPacScriptComplete(rv);
+        break;
+      default:
+        NOTREACHED() << "bad state";
+        rv = ERR_UNEXPECTED;
+        break;
+    }
+  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
+  return rv;
+}
+
+void ProxyScriptDecider::DoCallback(int result) {
+  DCHECK_NE(ERR_IO_PENDING, result);
+  DCHECK(!callback_.is_null());
+  callback_.Run(result);
+}
+
+int ProxyScriptDecider::DoWait() {
+  next_state_ = STATE_WAIT_COMPLETE;
+
+  // If no waiting is required, continue on to the next state.
+  if (wait_delay_.ToInternalValue() == 0)
+    return OK;
+
+  // Otherwise wait the specified amount of time.
+  wait_timer_.Start(FROM_HERE, wait_delay_, this,
+                    &ProxyScriptDecider::OnWaitTimerFired);
+  net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT);
+  return ERR_IO_PENDING;
+}
+
+int ProxyScriptDecider::DoWaitComplete(int result) {
+  DCHECK_EQ(OK, result);
+  if (wait_delay_.ToInternalValue() != 0) {
+    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT,
+                                      result);
+  }
+  next_state_ = GetStartState();
+  return OK;
+}
+
+int ProxyScriptDecider::DoFetchPacScript() {
+  DCHECK(fetch_pac_bytes_);
+
+  next_state_ = STATE_FETCH_PAC_SCRIPT_COMPLETE;
+
+  const PacSource& pac_source = current_pac_source();
+
+  GURL effective_pac_url;
+  DetermineURL(pac_source, &effective_pac_url);
+
+  net_log_.BeginEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT,
+                      base::Bind(&PacSource::NetLogCallback,
+                                 base::Unretained(&pac_source),
+                                 &effective_pac_url));
+
+  if (pac_source.type == PacSource::WPAD_DHCP) {
+    if (!dhcp_proxy_script_fetcher_) {
+      net_log_.AddEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER);
+      return ERR_UNEXPECTED;
+    }
+
+    return dhcp_proxy_script_fetcher_->Fetch(
+        &pac_script_, base::Bind(&ProxyScriptDecider::OnIOCompletion,
+                                 base::Unretained(this)));
+  }
+
+  if (!proxy_script_fetcher_) {
+    net_log_.AddEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER_HAS_NO_FETCHER);
+    return ERR_UNEXPECTED;
+  }
+
+  return proxy_script_fetcher_->Fetch(
+      effective_pac_url, &pac_script_,
+      base::Bind(&ProxyScriptDecider::OnIOCompletion, base::Unretained(this)));
+}
+
+int ProxyScriptDecider::DoFetchPacScriptComplete(int result) {
+  DCHECK(fetch_pac_bytes_);
+
+  net_log_.EndEventWithNetErrorCode(
+      NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT, result);
+  if (result != OK)
+    return TryToFallbackPacSource(result);
+
+  next_state_ = STATE_VERIFY_PAC_SCRIPT;
+  return result;
+}
+
+int ProxyScriptDecider::DoVerifyPacScript() {
+  next_state_ = STATE_VERIFY_PAC_SCRIPT_COMPLETE;
+
+  // This is just a heuristic. Ideally we would try to parse the script.
+  if (fetch_pac_bytes_ && !LooksLikePacScript(pac_script_))
+    return ERR_PAC_SCRIPT_FAILED;
+
+  return OK;
+}
+
+int ProxyScriptDecider::DoVerifyPacScriptComplete(int result) {
+  if (result != OK)
+    return TryToFallbackPacSource(result);
+
+  const PacSource& pac_source = current_pac_source();
+
+  // Extract the current script data.
+  if (fetch_pac_bytes_) {
+    script_data_ = ProxyResolverScriptData::FromUTF16(pac_script_);
+  } else {
+    script_data_ = pac_source.type == PacSource::CUSTOM ?
+        ProxyResolverScriptData::FromURL(pac_source.url) :
+        ProxyResolverScriptData::ForAutoDetect();
+  }
+
+  // Let the caller know which automatic setting we ended up initializing the
+  // resolver for (there may have been multiple fallbacks to choose from.)
+  if (current_pac_source().type == PacSource::CUSTOM) {
+    effective_config_ =
+        ProxyConfig::CreateFromCustomPacURL(current_pac_source().url);
+    effective_config_.set_pac_mandatory(pac_mandatory_);
+  } else {
+    if (fetch_pac_bytes_) {
+      GURL auto_detected_url;
+
+      switch (current_pac_source().type) {
+        case PacSource::WPAD_DHCP:
+          auto_detected_url = dhcp_proxy_script_fetcher_->GetPacURL();
+          break;
+
+        case PacSource::WPAD_DNS:
+          auto_detected_url = GURL(kWpadUrl);
+          break;
+
+        default:
+          NOTREACHED();
+      }
+
+      effective_config_ =
+          ProxyConfig::CreateFromCustomPacURL(auto_detected_url);
+    } else {
+      // The resolver does its own resolution so we cannot know the
+      // URL. Just do the best we can and state that the configuration
+      // is to auto-detect proxy settings.
+      effective_config_ = ProxyConfig::CreateAutoDetect();
+    }
+  }
+
+  return OK;
+}
+
+int ProxyScriptDecider::TryToFallbackPacSource(int error) {
+  DCHECK_LT(error, 0);
+
+  if (current_pac_source_index_ + 1 >= pac_sources_.size()) {
+    // Nothing left to fall back to.
+    return error;
+  }
+
+  // Advance to next URL in our list.
+  ++current_pac_source_index_;
+
+  net_log_.AddEvent(
+      NetLog::TYPE_PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE);
+
+  next_state_ = GetStartState();
+
+  return OK;
+}
+
+ProxyScriptDecider::State ProxyScriptDecider::GetStartState() const {
+  return fetch_pac_bytes_ ?  STATE_FETCH_PAC_SCRIPT : STATE_VERIFY_PAC_SCRIPT;
+}
+
+void ProxyScriptDecider::DetermineURL(const PacSource& pac_source,
+                                      GURL* effective_pac_url) {
+  DCHECK(effective_pac_url);
+
+  switch (pac_source.type) {
+    case PacSource::WPAD_DHCP:
+      break;
+    case PacSource::WPAD_DNS:
+      *effective_pac_url = GURL(kWpadUrl);
+      break;
+    case PacSource::CUSTOM:
+      *effective_pac_url = pac_source.url;
+      break;
+  }
+}
+
+const ProxyScriptDecider::PacSource&
+    ProxyScriptDecider::current_pac_source() const {
+  DCHECK_LT(current_pac_source_index_, pac_sources_.size());
+  return pac_sources_[current_pac_source_index_];
+}
+
+void ProxyScriptDecider::OnWaitTimerFired() {
+  OnIOCompletion(OK);
+}
+
+void ProxyScriptDecider::DidComplete() {
+  net_log_.EndEvent(NetLog::TYPE_PROXY_SCRIPT_DECIDER);
+}
+
+void ProxyScriptDecider::Cancel() {
+  DCHECK_NE(STATE_NONE, next_state_);
+
+  net_log_.AddEvent(NetLog::TYPE_CANCELLED);
+
+  switch (next_state_) {
+    case STATE_WAIT_COMPLETE:
+      wait_timer_.Stop();
+      break;
+    case STATE_FETCH_PAC_SCRIPT_COMPLETE:
+      proxy_script_fetcher_->Cancel();
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+
+  // This is safe to call in any state.
+  if (dhcp_proxy_script_fetcher_)
+    dhcp_proxy_script_fetcher_->Cancel();
+
+  DidComplete();
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_script_decider.h b/src/net/proxy/proxy_script_decider.h
new file mode 100644
index 0000000..a000c88
--- /dev/null
+++ b/src/net/proxy/proxy_script_decider.h
@@ -0,0 +1,184 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_SCRIPT_DECIDER_H_
+#define NET_PROXY_PROXY_SCRIPT_DECIDER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "base/string16.h"
+#include "base/time.h"
+#include "base/timer.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_resolver.h"
+
+namespace net {
+
+class DhcpProxyScriptFetcher;
+class NetLogParameter;
+class ProxyResolver;
+class ProxyScriptFetcher;
+
+// ProxyScriptDecider is a helper class used by ProxyService to determine which
+// PAC script to use given our proxy configuration.
+//
+// This involves trying to use PAC scripts in this order:
+//
+//   (1) WPAD (DHCP) if auto-detect is on.
+//   (2) WPAD (DNS) if auto-detect is on.
+//   (3) Custom PAC script if a URL was given.
+//
+// If no PAC script was successfully selected, then it fails with either a
+// network error, or PAC_SCRIPT_FAILED (indicating it did not pass our
+// validation).
+//
+// On successful completion, the fetched PAC script data can be accessed using
+// script_data().
+//
+// Deleting ProxyScriptDecider while Init() is in progress, will
+// cancel the request.
+//
+class NET_EXPORT_PRIVATE ProxyScriptDecider {
+ public:
+  // |proxy_script_fetcher|, |dhcp_proxy_script_fetcher| and
+  // |net_log| must remain valid for the lifespan of ProxyScriptDecider.
+  ProxyScriptDecider(ProxyScriptFetcher* proxy_script_fetcher,
+                     DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+                     NetLog* net_log);
+
+  // Aborts any in-progress request.
+  ~ProxyScriptDecider();
+
+  // Evaluates the effective proxy settings for |config|, and downloads the
+  // associated PAC script.
+  // If |wait_delay| is positive, the initialization will pause for this
+  // amount of time before getting started.
+  // On successful completion, the "effective" proxy settings we ended up
+  // deciding on will be available vial the effective_settings() accessor.
+  // Note that this may differ from |config| since we will have stripped any
+  // manual settings, and decided whether to use auto-detect or the custom PAC
+  // URL. Finally, if auto-detect was used we may now have resolved that to a
+  // specific script URL.
+  int Start(const ProxyConfig& config,
+            const base::TimeDelta wait_delay,
+            bool fetch_pac_bytes,
+            const net::CompletionCallback& callback);
+
+  const ProxyConfig& effective_config() const;
+
+  // TODO(eroman): Return a const-pointer.
+  ProxyResolverScriptData* script_data() const;
+
+ private:
+  // Represents the sources from which we can get PAC files; two types of
+  // auto-detect or a custom URL.
+  struct PacSource {
+    enum Type {
+      WPAD_DHCP,
+      WPAD_DNS,
+      CUSTOM
+    };
+
+    PacSource(Type type, const GURL& url)
+        : type(type), url(url) {}
+
+    // Returns a Value representing the PacSource.  |effective_pac_url| must
+    // be non-NULL and point to the URL derived from information contained in
+    // |this|, if Type is not WPAD_DHCP.
+    base::Value* NetLogCallback(const GURL* effective_pac_url,
+                                NetLog::LogLevel log_level) const;
+
+    Type type;
+    GURL url;  // Empty unless |type == PAC_SOURCE_CUSTOM|.
+  };
+
+  typedef std::vector<PacSource> PacSourceList;
+
+  enum State {
+    STATE_NONE,
+    STATE_WAIT,
+    STATE_WAIT_COMPLETE,
+    STATE_FETCH_PAC_SCRIPT,
+    STATE_FETCH_PAC_SCRIPT_COMPLETE,
+    STATE_VERIFY_PAC_SCRIPT,
+    STATE_VERIFY_PAC_SCRIPT_COMPLETE,
+  };
+
+  // Returns ordered list of PAC urls to try for |config|.
+  PacSourceList BuildPacSourcesFallbackList(const ProxyConfig& config) const;
+
+  void OnIOCompletion(int result);
+  int DoLoop(int result);
+  void DoCallback(int result);
+
+  int DoWait();
+  int DoWaitComplete(int result);
+
+  int DoFetchPacScript();
+  int DoFetchPacScriptComplete(int result);
+
+  int DoVerifyPacScript();
+  int DoVerifyPacScriptComplete(int result);
+
+  // Tries restarting using the next fallback PAC URL:
+  // |pac_sources_[++current_pac_source_index]|.
+  // Returns OK and rewinds the state machine when there
+  // is something to try, otherwise returns |error|.
+  int TryToFallbackPacSource(int error);
+
+  // Gets the initial state (we skip fetching when the
+  // ProxyResolver doesn't |expect_pac_bytes()|.
+  State GetStartState() const;
+
+  void DetermineURL(const PacSource& pac_source, GURL* effective_pac_url);
+
+  // Returns the current PAC URL we are fetching/testing.
+  const PacSource& current_pac_source() const;
+
+  void OnWaitTimerFired();
+  void DidComplete();
+  void Cancel();
+
+  ProxyResolver* resolver_;
+  ProxyScriptFetcher* proxy_script_fetcher_;
+  DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_;
+
+  net::CompletionCallback callback_;
+
+  size_t current_pac_source_index_;
+
+  // Filled when the PAC script fetch completes.
+  string16 pac_script_;
+
+  // Flag indicating whether the caller requested a mandatory pac script
+  // (i.e. fallback to direct connections are prohibited).
+  bool pac_mandatory_;
+
+  PacSourceList pac_sources_;
+  State next_state_;
+
+  BoundNetLog net_log_;
+
+  bool fetch_pac_bytes_;
+
+  base::TimeDelta wait_delay_;
+  base::OneShotTimer<ProxyScriptDecider> wait_timer_;
+
+  // Results.
+  ProxyConfig effective_config_;
+  scoped_refptr<ProxyResolverScriptData> script_data_;
+
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyScriptDecider);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_SCRIPT_DECIDER_H_
diff --git a/src/net/proxy/proxy_script_decider_unittest.cc b/src/net/proxy/proxy_script_decider_unittest.cc
new file mode 100644
index 0000000..62075c4
--- /dev/null
+++ b/src/net/proxy/proxy_script_decider_unittest.cc
@@ -0,0 +1,597 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/time.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/test_completion_callback.h"
+#include "net/proxy/dhcp_proxy_script_fetcher.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_resolver.h"
+#include "net/proxy/proxy_script_decider.h"
+#include "net/proxy/proxy_script_fetcher.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace {
+
+enum Error {
+  kFailedDownloading = -100,
+  kFailedParsing = ERR_PAC_SCRIPT_FAILED,
+};
+
+class Rules {
+ public:
+  struct Rule {
+    Rule(const GURL& url, int fetch_error, bool is_valid_script)
+        : url(url),
+          fetch_error(fetch_error),
+          is_valid_script(is_valid_script) {
+    }
+
+    string16 text() const {
+      if (is_valid_script)
+        return UTF8ToUTF16(url.spec() + "!FindProxyForURL");
+      if (fetch_error == OK)
+        return UTF8ToUTF16(url.spec() + "!invalid-script");
+      return string16();
+    }
+
+    GURL url;
+    int fetch_error;
+    bool is_valid_script;
+  };
+
+  Rule AddSuccessRule(const char* url) {
+    Rule rule(GURL(url), OK /*fetch_error*/, true);
+    rules_.push_back(rule);
+    return rule;
+  }
+
+  void AddFailDownloadRule(const char* url) {
+    rules_.push_back(Rule(GURL(url), kFailedDownloading /*fetch_error*/,
+        false));
+  }
+
+  void AddFailParsingRule(const char* url) {
+    rules_.push_back(Rule(GURL(url), OK /*fetch_error*/, false));
+  }
+
+  const Rule& GetRuleByUrl(const GURL& url) const {
+    for (RuleList::const_iterator it = rules_.begin(); it != rules_.end();
+         ++it) {
+      if (it->url == url)
+        return *it;
+    }
+    LOG(FATAL) << "Rule not found for " << url;
+    return rules_[0];
+  }
+
+  const Rule& GetRuleByText(const string16& text) const {
+    for (RuleList::const_iterator it = rules_.begin(); it != rules_.end();
+         ++it) {
+      if (it->text() == text)
+        return *it;
+    }
+    LOG(FATAL) << "Rule not found for " << text;
+    return rules_[0];
+  }
+
+ private:
+  typedef std::vector<Rule> RuleList;
+  RuleList rules_;
+};
+
+class RuleBasedProxyScriptFetcher : public ProxyScriptFetcher {
+ public:
+  explicit RuleBasedProxyScriptFetcher(const Rules* rules) : rules_(rules) {}
+
+  // ProxyScriptFetcher implementation.
+  virtual int Fetch(const GURL& url,
+                    string16* text,
+                    const CompletionCallback& callback) {
+    const Rules::Rule& rule = rules_->GetRuleByUrl(url);
+    int rv = rule.fetch_error;
+    EXPECT_NE(ERR_UNEXPECTED, rv);
+    if (rv == OK)
+      *text = rule.text();
+    return rv;
+  }
+
+  virtual void Cancel() {}
+
+  virtual URLRequestContext* GetRequestContext() const { return NULL; }
+
+ private:
+  const Rules* rules_;
+};
+
+// Succeed using custom PAC script.
+TEST(ProxyScriptDeciderTest, CustomPacSucceeds) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  CapturingNetLog log;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
+  EXPECT_EQ(OK, decider.Start(
+      config, base::TimeDelta(), true, callback.callback()));
+  EXPECT_EQ(rule.text(), decider.script_data()->utf16());
+
+  // Check the NetLog was filled correctly.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(4u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 1, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 3, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+
+  EXPECT_TRUE(decider.effective_config().has_pac_url());
+  EXPECT_EQ(config.pac_url(), decider.effective_config().pac_url());
+}
+
+// Fail downloading the custom PAC script.
+TEST(ProxyScriptDeciderTest, CustomPacFails1) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailDownloadRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  CapturingNetLog log;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
+  EXPECT_EQ(kFailedDownloading,
+            decider.Start(config, base::TimeDelta(), true,
+                          callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+
+  // Check the NetLog was filled correctly.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(4u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 1, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 3, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+
+  EXPECT_FALSE(decider.effective_config().has_pac_url());
+}
+
+// Fail parsing the custom PAC script.
+TEST(ProxyScriptDeciderTest, CustomPacFails2) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailParsingRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  EXPECT_EQ(kFailedParsing,
+            decider.Start(config, base::TimeDelta(), true,
+                          callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+}
+
+// Fail downloading the custom PAC script, because the fetcher was NULL.
+TEST(ProxyScriptDeciderTest, HasNullProxyScriptFetcher) {
+  Rules rules;
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(NULL, &dhcp_fetcher, NULL);
+  EXPECT_EQ(ERR_UNEXPECTED,
+            decider.Start(config, base::TimeDelta(), true,
+                          callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+}
+
+// Succeeds in choosing autodetect (WPAD DNS).
+TEST(ProxyScriptDeciderTest, AutodetectSuccess) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+
+  Rules::Rule rule = rules.AddSuccessRule("http://wpad/wpad.dat");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  EXPECT_EQ(OK, decider.Start(
+      config, base::TimeDelta(), true, callback.callback()));
+  EXPECT_EQ(rule.text(), decider.script_data()->utf16());
+
+  EXPECT_TRUE(decider.effective_config().has_pac_url());
+  EXPECT_EQ(rule.url, decider.effective_config().pac_url());
+}
+
+// Fails at WPAD (downloading), but succeeds in choosing the custom PAC.
+TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess1) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailDownloadRule("http://wpad/wpad.dat");
+  Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  EXPECT_EQ(OK, decider.Start(
+      config, base::TimeDelta(), true, callback.callback()));
+  EXPECT_EQ(rule.text(), decider.script_data()->utf16());
+
+  EXPECT_TRUE(decider.effective_config().has_pac_url());
+  EXPECT_EQ(rule.url, decider.effective_config().pac_url());
+}
+
+// Fails at WPAD (no DHCP config, DNS PAC fails parsing), but succeeds in
+// choosing the custom PAC.
+TEST(ProxyScriptDeciderTest, AutodetectFailCustomSuccess2) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+  config.proxy_rules().ParseFromString("unused-manual-proxy:99");
+
+  rules.AddFailParsingRule("http://wpad/wpad.dat");
+  Rules::Rule rule = rules.AddSuccessRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  CapturingNetLog log;
+
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
+  EXPECT_EQ(OK, decider.Start(config, base::TimeDelta(),
+                          true, callback.callback()));
+  EXPECT_EQ(rule.text(), decider.script_data()->utf16());
+
+  // Verify that the effective configuration no longer contains auto detect or
+  // any of the manual settings.
+  EXPECT_TRUE(decider.effective_config().Equals(
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://custom/proxy.pac"))));
+
+  // Check the NetLog was filled correctly.
+  // (Note that various states are repeated since both WPAD and custom
+  // PAC scripts are tried).
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(10u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+  // This is the DHCP phase, which fails fetching rather than parsing, so
+  // there is no pair of SET_PAC_SCRIPT events.
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 1, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEvent(
+      entries, 3,
+      NetLog::TYPE_PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE,
+      NetLog::PHASE_NONE));
+  // This is the DNS phase, which attempts a fetch but fails.
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 4, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 5, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEvent(
+      entries, 6,
+      NetLog::TYPE_PROXY_SCRIPT_DECIDER_FALLING_BACK_TO_NEXT_PAC_SOURCE,
+      NetLog::PHASE_NONE));
+  // Finally, the custom PAC URL phase.
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 7, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 8, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 9, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+}
+
+// Fails at WPAD (downloading), and fails at custom PAC (downloading).
+TEST(ProxyScriptDeciderTest, AutodetectFailCustomFails1) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailDownloadRule("http://wpad/wpad.dat");
+  rules.AddFailDownloadRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  EXPECT_EQ(kFailedDownloading,
+            decider.Start(config, base::TimeDelta(), true,
+                          callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+}
+
+// Fails at WPAD (downloading), and fails at custom PAC (parsing).
+TEST(ProxyScriptDeciderTest, AutodetectFailCustomFails2) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailDownloadRule("http://wpad/wpad.dat");
+  rules.AddFailParsingRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  EXPECT_EQ(kFailedParsing,
+            decider.Start(config, base::TimeDelta(), true,
+                          callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+}
+
+// This is a copy-paste of CustomPacFails1, with the exception that we give it
+// a 1 millisecond delay. This means it will now complete asynchronously.
+// Moreover, we test the NetLog to make sure it logged the pause.
+TEST(ProxyScriptDeciderTest, CustomPacFails1_WithPositiveDelay) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailDownloadRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  CapturingNetLog log;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
+  EXPECT_EQ(ERR_IO_PENDING,
+            decider.Start(config, base::TimeDelta::FromMilliseconds(1),
+                      true, callback.callback()));
+
+  EXPECT_EQ(kFailedDownloading, callback.WaitForResult());
+  EXPECT_EQ(NULL, decider.script_data());
+
+  // Check the NetLog was filled correctly.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(6u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 1, NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SCRIPT_DECIDER_WAIT));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 3, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 4, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 5, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+}
+
+// This is a copy-paste of CustomPacFails1, with the exception that we give it
+// a -5 second delay instead of a 0 ms delay. This change should have no effect
+// so the rest of the test is unchanged.
+TEST(ProxyScriptDeciderTest, CustomPacFails1_WithNegativeDelay) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  DoNothingDhcpProxyScriptFetcher dhcp_fetcher;
+
+  ProxyConfig config;
+  config.set_pac_url(GURL("http://custom/proxy.pac"));
+
+  rules.AddFailDownloadRule("http://custom/proxy.pac");
+
+  TestCompletionCallback callback;
+  CapturingNetLog log;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, &log);
+  EXPECT_EQ(kFailedDownloading,
+            decider.Start(config, base::TimeDelta::FromSeconds(-5),
+                          true, callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+
+  // Check the NetLog was filled correctly.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(4u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 1, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SCRIPT_DECIDER_FETCH_PAC_SCRIPT));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 3, NetLog::TYPE_PROXY_SCRIPT_DECIDER));
+}
+
+class SynchronousSuccessDhcpFetcher : public DhcpProxyScriptFetcher {
+ public:
+  explicit SynchronousSuccessDhcpFetcher(const string16& expected_text)
+      : gurl_("http://dhcppac/"), expected_text_(expected_text) {
+  }
+
+  int Fetch(string16* utf16_text, const CompletionCallback& callback) OVERRIDE {
+    *utf16_text = expected_text_;
+    return OK;
+  }
+
+  void Cancel() OVERRIDE {
+  }
+
+  const GURL& GetPacURL() const OVERRIDE {
+    return gurl_;
+  }
+
+  const string16& expected_text() const {
+    return expected_text_;
+  }
+
+ private:
+  GURL gurl_;
+  string16 expected_text_;
+
+  DISALLOW_COPY_AND_ASSIGN(SynchronousSuccessDhcpFetcher);
+};
+
+// All of the tests above that use ProxyScriptDecider have tested
+// failure to fetch a PAC file via DHCP configuration, so we now test
+// success at downloading and parsing, and then success at downloading,
+// failure at parsing.
+
+TEST(ProxyScriptDeciderTest, AutodetectDhcpSuccess) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  SynchronousSuccessDhcpFetcher dhcp_fetcher(
+      WideToUTF16(L"http://bingo/!FindProxyForURL"));
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+
+  rules.AddSuccessRule("http://bingo/");
+  rules.AddFailDownloadRule("http://wpad/wpad.dat");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  EXPECT_EQ(OK, decider.Start(
+      config, base::TimeDelta(), true, callback.callback()));
+  EXPECT_EQ(dhcp_fetcher.expected_text(),
+            decider.script_data()->utf16());
+
+  EXPECT_TRUE(decider.effective_config().has_pac_url());
+  EXPECT_EQ(GURL("http://dhcppac/"), decider.effective_config().pac_url());
+}
+
+TEST(ProxyScriptDeciderTest, AutodetectDhcpFailParse) {
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+  SynchronousSuccessDhcpFetcher dhcp_fetcher(
+      WideToUTF16(L"http://bingo/!invalid-script"));
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+
+  rules.AddFailParsingRule("http://bingo/");
+  rules.AddFailDownloadRule("http://wpad/wpad.dat");
+
+  TestCompletionCallback callback;
+  ProxyScriptDecider decider(&fetcher, &dhcp_fetcher, NULL);
+  // Since there is fallback to DNS-based WPAD, the final error will be that
+  // it failed downloading, not that it failed parsing.
+  EXPECT_EQ(kFailedDownloading,
+      decider.Start(config, base::TimeDelta(), true, callback.callback()));
+  EXPECT_EQ(NULL, decider.script_data());
+
+  EXPECT_FALSE(decider.effective_config().has_pac_url());
+}
+
+class AsyncFailDhcpFetcher
+    : public DhcpProxyScriptFetcher,
+      public base::SupportsWeakPtr<AsyncFailDhcpFetcher> {
+ public:
+  AsyncFailDhcpFetcher() {}
+  ~AsyncFailDhcpFetcher() {}
+
+  int Fetch(string16* utf16_text, const CompletionCallback& callback) OVERRIDE {
+    callback_ = callback;
+    MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(&AsyncFailDhcpFetcher::CallbackWithFailure, AsWeakPtr()));
+    return ERR_IO_PENDING;
+  }
+
+  void Cancel() OVERRIDE {
+    callback_.Reset();
+  }
+
+  const GURL& GetPacURL() const OVERRIDE {
+    return dummy_gurl_;
+  }
+
+  void CallbackWithFailure() {
+    if (!callback_.is_null())
+      callback_.Run(ERR_PAC_NOT_IN_DHCP);
+  }
+
+ private:
+  GURL dummy_gurl_;
+  CompletionCallback callback_;
+};
+
+TEST(ProxyScriptDeciderTest, DhcpCancelledByDestructor) {
+  // This regression test would crash before
+  // http://codereview.chromium.org/7044058/
+  // Thus, we don't care much about actual results (hence no EXPECT or ASSERT
+  // macros below), just that it doesn't crash.
+  Rules rules;
+  RuleBasedProxyScriptFetcher fetcher(&rules);
+
+  scoped_ptr<AsyncFailDhcpFetcher> dhcp_fetcher(new AsyncFailDhcpFetcher());
+
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  rules.AddFailDownloadRule("http://wpad/wpad.dat");
+
+  TestCompletionCallback callback;
+
+  // Scope so ProxyScriptDecider gets destroyed early.
+  {
+    ProxyScriptDecider decider(&fetcher, dhcp_fetcher.get(), NULL);
+    decider.Start(config, base::TimeDelta(), true, callback.callback());
+  }
+
+  // Run the message loop to let the DHCP fetch complete and post the results
+  // back. Before the fix linked to above, this would try to invoke on
+  // the callback object provided by ProxyScriptDecider after it was
+  // no longer valid.
+  MessageLoop::current()->RunUntilIdle();
+}
+
+}  // namespace
+}  // namespace net
diff --git a/src/net/proxy/proxy_script_fetcher.h b/src/net/proxy/proxy_script_fetcher.h
new file mode 100644
index 0000000..b472fd8
--- /dev/null
+++ b/src/net/proxy/proxy_script_fetcher.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ProxyScriptFetcher is an async interface for fetching a proxy auto config
+// script. It is specific to fetching a PAC script; enforces timeout, max-size,
+// status code.
+
+#ifndef NET_PROXY_PROXY_SCRIPT_FETCHER_H_
+#define NET_PROXY_PROXY_SCRIPT_FETCHER_H_
+
+#include "base/string16.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_export.h"
+
+class GURL;
+
+namespace net {
+
+class URLRequestContext;
+
+// Interface for downloading a PAC script. Implementations can enforce
+// timeouts, maximum size constraints, content encoding, etc..
+class NET_EXPORT_PRIVATE ProxyScriptFetcher {
+ public:
+  // Destruction should cancel any outstanding requests.
+  virtual ~ProxyScriptFetcher() {}
+
+  // Downloads the given PAC URL, and invokes |callback| on completion.
+  // Returns OK on success, otherwise the error code. If the return code is
+  // ERR_IO_PENDING, then the request completes asynchronously, and |callback|
+  // will be invoked later with the final error code.
+  // After synchronous or asynchronous completion with a result code of OK,
+  // |*utf16_text| is filled with the response. On failure, the result text is
+  // an empty string, and the result code is a network error. Some special
+  // network errors that may occur are:
+  //
+  //    ERR_TIMED_OUT         -- the fetch took too long to complete.
+  //    ERR_FILE_TOO_BIG      -- the response's body was too large.
+  //    ERR_PAC_STATUS_NOT_OK -- non-200 HTTP status code.
+  //    ERR_NOT_IMPLEMENTED   -- the response required authentication.
+  //
+  // If the request is cancelled (either using the "Cancel()" method or by
+  // deleting |this|), then no callback is invoked.
+  //
+  // Only one fetch is allowed to be outstanding at a time.
+  virtual int Fetch(const GURL& url, string16* utf16_text,
+                    const net::CompletionCallback& callback) = 0;
+
+  // Aborts the in-progress fetch (if any).
+  virtual void Cancel() = 0;
+
+  // Returns the request context that this fetcher uses to issue downloads,
+  // or NULL.
+  virtual URLRequestContext* GetRequestContext() const = 0;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_SCRIPT_FETCHER_H_
diff --git a/src/net/proxy/proxy_script_fetcher_impl.cc b/src/net/proxy/proxy_script_fetcher_impl.cc
new file mode 100644
index 0000000..6c1b4f2
--- /dev/null
+++ b/src/net/proxy/proxy_script_fetcher_impl.cc
@@ -0,0 +1,321 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_script_fetcher_impl.h"
+
+#include "base/compiler_specific.h"
+#include "base/i18n/icu_string_conversions.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "net/base/cert_status_flags.h"
+#include "net/base/data_url.h"
+#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request_context.h"
+
+// TODO(eroman):
+//   - Support auth-prompts (http://crbug.com/77366)
+
+namespace net {
+
+namespace {
+
+// The maximum size (in bytes) allowed for a PAC script. Responses exceeding
+// this will fail with ERR_FILE_TOO_BIG.
+const int kDefaultMaxResponseBytes = 1048576;  // 1 megabyte
+
+// The maximum duration (in milliseconds) allowed for fetching the PAC script.
+// Responses exceeding this will fail with ERR_TIMED_OUT.
+const int kDefaultMaxDurationMs = 300000;  // 5 minutes
+
+// Returns true if |mime_type| is one of the known PAC mime type.
+bool IsPacMimeType(const std::string& mime_type) {
+  static const char * const kSupportedPacMimeTypes[] = {
+    "application/x-ns-proxy-autoconfig",
+    "application/x-javascript-config",
+  };
+  for (size_t i = 0; i < arraysize(kSupportedPacMimeTypes); ++i) {
+    if (LowerCaseEqualsASCII(mime_type, kSupportedPacMimeTypes[i]))
+      return true;
+  }
+  return false;
+}
+
+// Converts |bytes| (which is encoded by |charset|) to UTF16, saving the resul
+// to |*utf16|.
+// If |charset| is empty, then we don't know what it was and guess.
+void ConvertResponseToUTF16(const std::string& charset,
+                            const std::string& bytes,
+                            string16* utf16) {
+  const char* codepage;
+
+  if (charset.empty()) {
+    // Assume ISO-8859-1 if no charset was specified.
+    codepage = base::kCodepageLatin1;
+  } else {
+    // Otherwise trust the charset that was provided.
+    codepage = charset.c_str();
+  }
+
+  // We will be generous in the conversion -- if any characters lie
+  // outside of |charset| (i.e. invalid), then substitute them with
+  // U+FFFD rather than failing.
+  base::CodepageToUTF16(bytes, codepage,
+                        base::OnStringConversionError::SUBSTITUTE,
+                        utf16);
+}
+
+}  // namespace
+
+ProxyScriptFetcherImpl::ProxyScriptFetcherImpl(
+    URLRequestContext* url_request_context)
+    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+      url_request_context_(url_request_context),
+      buf_(new IOBuffer(kBufSize)),
+      next_id_(0),
+      cur_request_(NULL),
+      cur_request_id_(0),
+      result_code_(OK),
+      result_text_(NULL),
+      max_response_bytes_(kDefaultMaxResponseBytes),
+      max_duration_(base::TimeDelta::FromMilliseconds(kDefaultMaxDurationMs)) {
+  DCHECK(url_request_context);
+}
+
+ProxyScriptFetcherImpl::~ProxyScriptFetcherImpl() {
+  // The URLRequest's destructor will cancel the outstanding request, and
+  // ensure that the delegate (this) is not called again.
+}
+
+base::TimeDelta ProxyScriptFetcherImpl::SetTimeoutConstraint(
+    base::TimeDelta timeout) {
+  base::TimeDelta prev = max_duration_;
+  max_duration_ = timeout;
+  return prev;
+}
+
+size_t ProxyScriptFetcherImpl::SetSizeConstraint(size_t size_bytes) {
+  size_t prev = max_response_bytes_;
+  max_response_bytes_ = size_bytes;
+  return prev;
+}
+
+void ProxyScriptFetcherImpl::OnResponseCompleted(URLRequest* request) {
+  DCHECK_EQ(request, cur_request_.get());
+
+  // Use |result_code_| as the request's error if we have already set it to
+  // something specific.
+  if (result_code_ == OK && !request->status().is_success())
+    result_code_ = request->status().error();
+
+  FetchCompleted();
+}
+
+int ProxyScriptFetcherImpl::Fetch(
+    const GURL& url, string16* text, const CompletionCallback& callback) {
+  // It is invalid to call Fetch() while a request is already in progress.
+  DCHECK(!cur_request_.get());
+  DCHECK(!callback.is_null());
+  DCHECK(text);
+
+  // Handle base-64 encoded data-urls that contain custom PAC scripts.
+  if (url.SchemeIs("data")) {
+    std::string mime_type;
+    std::string charset;
+    std::string data;
+    if (!DataURL::Parse(url, &mime_type, &charset, &data))
+      return ERR_FAILED;
+
+    ConvertResponseToUTF16(charset, data, text);
+    return OK;
+  }
+
+  cur_request_.reset(url_request_context_->CreateRequest(url, this));
+  cur_request_->set_method("GET");
+
+  // Make sure that the PAC script is downloaded using a direct connection,
+  // to avoid circular dependencies (fetching is a part of proxy resolution).
+  // Also disable the use of the disk cache. The cache is disabled so that if
+  // the user switches networks we don't potentially use the cached response
+  // from old network when we should in fact be re-fetching on the new network.
+  // If the PAC script is hosted on an HTTPS server we bypass revocation
+  // checking in order to avoid a circular dependency when attempting to fetch
+  // the OCSP response or CRL. We could make the revocation check go direct but
+  // the proxy might be the only way to the outside world.
+  cur_request_->set_load_flags(LOAD_BYPASS_PROXY | LOAD_DISABLE_CACHE |
+                               LOAD_DISABLE_CERT_REVOCATION_CHECKING);
+
+  // Save the caller's info for notification on completion.
+  callback_ = callback;
+  result_text_ = text;
+
+  bytes_read_so_far_.clear();
+
+  // Post a task to timeout this request if it takes too long.
+  cur_request_id_ = ++next_id_;
+  MessageLoop::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&ProxyScriptFetcherImpl::OnTimeout, weak_factory_.GetWeakPtr(),
+                 cur_request_id_),
+      max_duration_);
+
+  // Start the request.
+  cur_request_->Start();
+  return ERR_IO_PENDING;
+}
+
+void ProxyScriptFetcherImpl::Cancel() {
+  // ResetCurRequestState will free the URLRequest, which will cause
+  // cancellation.
+  ResetCurRequestState();
+}
+
+URLRequestContext* ProxyScriptFetcherImpl::GetRequestContext() const {
+  return url_request_context_;
+}
+
+void ProxyScriptFetcherImpl::OnAuthRequired(URLRequest* request,
+                                            AuthChallengeInfo* auth_info) {
+  DCHECK_EQ(request, cur_request_.get());
+  // TODO(eroman): http://crbug.com/77366
+  LOG(WARNING) << "Auth required to fetch PAC script, aborting.";
+  result_code_ = ERR_NOT_IMPLEMENTED;
+  request->CancelAuth();
+}
+
+void ProxyScriptFetcherImpl::OnSSLCertificateError(URLRequest* request,
+                                                   const SSLInfo& ssl_info,
+                                                   bool fatal) {
+  DCHECK_EQ(request, cur_request_.get());
+  // Revocation check failures are not fatal.
+  if (IsCertStatusMinorError(ssl_info.cert_status)) {
+    request->ContinueDespiteLastError();
+    return;
+  }
+  LOG(WARNING) << "SSL certificate error when fetching PAC script, aborting.";
+  // Certificate errors are in same space as net errors.
+  result_code_ = MapCertStatusToNetError(ssl_info.cert_status);
+  request->Cancel();
+}
+
+void ProxyScriptFetcherImpl::OnResponseStarted(URLRequest* request) {
+  DCHECK_EQ(request, cur_request_.get());
+
+  if (!request->status().is_success()) {
+    OnResponseCompleted(request);
+    return;
+  }
+
+  // Require HTTP responses to have a success status code.
+  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
+    // NOTE about status codes: We are like Firefox 3 in this respect.
+    // {IE 7, Safari 3, Opera 9.5} do not care about the status code.
+    if (request->GetResponseCode() != 200) {
+      VLOG(1) << "Fetched PAC script had (bad) status line: "
+              << request->response_headers()->GetStatusLine();
+      result_code_ = ERR_PAC_STATUS_NOT_OK;
+      request->Cancel();
+      return;
+    }
+
+    // NOTE about mime types: We do not enforce mime types on PAC files.
+    // This is for compatibility with {IE 7, Firefox 3, Opera 9.5}. We will
+    // however log mismatches to help with debugging.
+    std::string mime_type;
+    cur_request_->GetMimeType(&mime_type);
+    if (!IsPacMimeType(mime_type)) {
+      VLOG(1) << "Fetched PAC script does not have a proper mime type: "
+              << mime_type;
+    }
+  }
+
+  ReadBody(request);
+}
+
+void ProxyScriptFetcherImpl::OnReadCompleted(URLRequest* request,
+                                             int num_bytes) {
+  DCHECK_EQ(request, cur_request_.get());
+  if (ConsumeBytesRead(request, num_bytes)) {
+    // Keep reading.
+    ReadBody(request);
+  }
+}
+
+void ProxyScriptFetcherImpl::ReadBody(URLRequest* request) {
+  // Read as many bytes as are available synchronously.
+  while (true) {
+    int num_bytes;
+    if (!request->Read(buf_, kBufSize, &num_bytes)) {
+      // Check whether the read failed synchronously.
+      if (!request->status().is_io_pending())
+        OnResponseCompleted(request);
+      return;
+    }
+    if (!ConsumeBytesRead(request, num_bytes))
+      return;
+  }
+}
+
+bool ProxyScriptFetcherImpl::ConsumeBytesRead(URLRequest* request,
+                                              int num_bytes) {
+  if (num_bytes <= 0) {
+    // Error while reading, or EOF.
+    OnResponseCompleted(request);
+    return false;
+  }
+
+  // Enforce maximum size bound.
+  if (num_bytes + bytes_read_so_far_.size() >
+      static_cast<size_t>(max_response_bytes_)) {
+    result_code_ = ERR_FILE_TOO_BIG;
+    request->Cancel();
+    return false;
+  }
+
+  bytes_read_so_far_.append(buf_->data(), num_bytes);
+  return true;
+}
+
+void ProxyScriptFetcherImpl::FetchCompleted() {
+  if (result_code_ == OK) {
+    // The caller expects the response to be encoded as UTF16.
+    std::string charset;
+    cur_request_->GetCharset(&charset);
+    ConvertResponseToUTF16(charset, bytes_read_so_far_, result_text_);
+  } else {
+    // On error, the caller expects empty string for bytes.
+    result_text_->clear();
+  }
+
+  int result_code = result_code_;
+  CompletionCallback callback = callback_;
+
+  ResetCurRequestState();
+
+  callback.Run(result_code);
+}
+
+void ProxyScriptFetcherImpl::ResetCurRequestState() {
+  cur_request_.reset();
+  cur_request_id_ = 0;
+  callback_.Reset();
+  result_code_ = OK;
+  result_text_ = NULL;
+}
+
+void ProxyScriptFetcherImpl::OnTimeout(int id) {
+  // Timeout tasks may outlive the URLRequest they reference. Make sure it
+  // is still applicable.
+  if (cur_request_id_ != id)
+    return;
+
+  DCHECK(cur_request_.get());
+  result_code_ = ERR_TIMED_OUT;
+  cur_request_->Cancel();
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_script_fetcher_impl.h b/src/net/proxy/proxy_script_fetcher_impl.h
new file mode 100644
index 0000000..7ce4d35
--- /dev/null
+++ b/src/net/proxy/proxy_script_fetcher_impl.h
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_PROXY_SCRIPT_FETCHER_IMPL_H_
+#define NET_PROXY_PROXY_SCRIPT_FETCHER_IMPL_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/string16.h"
+#include "base/time.h"
+#include "net/proxy/proxy_script_fetcher.h"
+#include "net/url_request/url_request.h"
+
+class GURL;
+
+namespace net {
+
+class URLRequestContext;
+
+// Implementation of ProxyScriptFetcher that downloads scripts using the
+// specified request context.
+class NET_EXPORT ProxyScriptFetcherImpl : public ProxyScriptFetcher,
+                                          public URLRequest::Delegate {
+ public:
+  // Creates a ProxyScriptFetcher that issues requests through
+  // |url_request_context|. |url_request_context| must remain valid for the
+  // lifetime of ProxyScriptFetcherImpl.
+  // Note that while a request is in progress, we will be holding a reference
+  // to |url_request_context|. Be careful not to create cycles between the
+  // fetcher and the context; you can break such cycles by calling Cancel().
+  explicit ProxyScriptFetcherImpl(URLRequestContext* url_request_context);
+
+  virtual ~ProxyScriptFetcherImpl();
+
+  // Used by unit-tests to modify the default limits.
+  base::TimeDelta SetTimeoutConstraint(base::TimeDelta timeout);
+  size_t SetSizeConstraint(size_t size_bytes);
+
+  void OnResponseCompleted(URLRequest* request);
+
+  // ProxyScriptFetcher methods:
+  virtual int Fetch(const GURL& url, string16* text,
+                    const net::CompletionCallback& callback) OVERRIDE;
+  virtual void Cancel() OVERRIDE;
+  virtual URLRequestContext* GetRequestContext() const OVERRIDE;
+
+  // URLRequest::Delegate methods:
+  virtual void OnAuthRequired(URLRequest* request,
+                              AuthChallengeInfo* auth_info) OVERRIDE;
+  virtual void OnSSLCertificateError(URLRequest* request,
+                                     const SSLInfo& ssl_info,
+                                     bool is_hsts_ok) OVERRIDE;
+  virtual void OnResponseStarted(URLRequest* request) OVERRIDE;
+  virtual void OnReadCompleted(URLRequest* request, int num_bytes) OVERRIDE;
+
+ private:
+  enum { kBufSize = 4096 };
+
+  // Read more bytes from the response.
+  void ReadBody(URLRequest* request);
+
+  // Handles a response from Read(). Returns true if we should continue trying
+  // to read. |num_bytes| is 0 for EOF, and < 0 on errors.
+  bool ConsumeBytesRead(URLRequest* request, int num_bytes);
+
+  // Called once the request has completed to notify the caller of
+  // |response_code_| and |response_text_|.
+  void FetchCompleted();
+
+  // Clear out the state for the current request.
+  void ResetCurRequestState();
+
+  // Callback for time-out task of request with id |id|.
+  void OnTimeout(int id);
+
+  // Factory for creating the time-out task. This takes care of revoking
+  // outstanding tasks when |this| is deleted.
+  base::WeakPtrFactory<ProxyScriptFetcherImpl> weak_factory_;
+
+  // The context used for making network requests.
+  URLRequestContext* const url_request_context_;
+
+  // Buffer that URLRequest writes into.
+  scoped_refptr<IOBuffer> buf_;
+
+  // The next ID to use for |cur_request_| (monotonically increasing).
+  int next_id_;
+
+  // The current (in progress) request, or NULL.
+  scoped_ptr<URLRequest> cur_request_;
+
+  // State for current request (only valid when |cur_request_| is not NULL):
+
+  // Unique ID for the current request.
+  int cur_request_id_;
+
+  // Callback to invoke on completion of the fetch.
+  net::CompletionCallback callback_;
+
+  // Holds the error condition that was hit on the current request, or OK.
+  int result_code_;
+
+  // Holds the bytes read so far. Will not exceed |max_response_bytes|.
+  std::string bytes_read_so_far_;
+
+  // This buffer is owned by the owner of |callback|, and will be filled with
+  // UTF16 response on completion.
+  string16* result_text_;
+
+  // The maximum number of bytes to allow in responses.
+  size_t max_response_bytes_;
+
+  // The maximum amount of time to wait for download to complete.
+  base::TimeDelta max_duration_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyScriptFetcherImpl);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_SCRIPT_FETCHER_IMPL_H_
diff --git a/src/net/proxy/proxy_script_fetcher_impl_unittest.cc b/src/net/proxy/proxy_script_fetcher_impl_unittest.cc
new file mode 100644
index 0000000..a061bea
--- /dev/null
+++ b/src/net/proxy/proxy_script_fetcher_impl_unittest.cc
@@ -0,0 +1,507 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_script_fetcher_impl.h"
+
+#include <string>
+
+#include "base/file_path.h"
+#include "base/compiler_specific.h"
+#include "base/path_service.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/mock_cert_verifier.h"
+#include "net/base/mock_host_resolver.h"
+#include "net/base/net_util.h"
+#include "net/base/load_flags.h"
+#include "net/base/ssl_config_service_defaults.h"
+#include "net/base/test_completion_callback.h"
+#include "net/disk_cache/disk_cache.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_network_session.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/test/test_server.h"
+#include "net/url_request/url_request_context_storage.h"
+#include "net/url_request/url_request_file_job.h"
+#include "net/url_request/url_request_job_factory_impl.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace net {
+
+// TODO(eroman):
+//   - Test canceling an outstanding request.
+//   - Test deleting ProxyScriptFetcher while a request is in progress.
+
+namespace {
+
+const FilePath::CharType kDocRoot[] =
+    FILE_PATH_LITERAL("net/data/proxy_script_fetcher_unittest");
+
+struct FetchResult {
+  int code;
+  string16 text;
+};
+
+// CheckNoRevocationFlagSetInterceptor causes a test failure if a request is
+// seen that doesn't set a load flag to bypass revocation checking.
+class CheckNoRevocationFlagSetInterceptor :
+    public URLRequestJobFactory::Interceptor {
+ public:
+  virtual URLRequestJob* MaybeIntercept(
+      URLRequest* request, NetworkDelegate* network_delegate) const OVERRIDE {
+    EXPECT_TRUE(request->load_flags() & LOAD_DISABLE_CERT_REVOCATION_CHECKING);
+    return NULL;
+  }
+
+  virtual URLRequestJob* MaybeInterceptRedirect(
+      const GURL& location,
+      URLRequest* request,
+      NetworkDelegate* network_delegate) const OVERRIDE {
+    return NULL;
+  }
+
+  virtual URLRequestJob* MaybeInterceptResponse(
+      URLRequest* request, NetworkDelegate* network_delegate) const OVERRIDE {
+    return NULL;
+  }
+};
+
+// A non-mock URL request which can access http:// and file:// urls.
+class RequestContext : public URLRequestContext {
+ public:
+  RequestContext() : ALLOW_THIS_IN_INITIALIZER_LIST(storage_(this)) {
+    ProxyConfig no_proxy;
+    storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver));
+    storage_.set_cert_verifier(new MockCertVerifier);
+    storage_.set_proxy_service(ProxyService::CreateFixed(no_proxy));
+    storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
+    storage_.set_http_server_properties(new HttpServerPropertiesImpl);
+
+    HttpNetworkSession::Params params;
+    params.host_resolver = host_resolver();
+    params.cert_verifier = cert_verifier();
+    params.proxy_service = proxy_service();
+    params.ssl_config_service = ssl_config_service();
+    params.http_server_properties = http_server_properties();
+    scoped_refptr<HttpNetworkSession> network_session(
+        new HttpNetworkSession(params));
+    storage_.set_http_transaction_factory(new HttpCache(
+        network_session,
+        HttpCache::DefaultBackend::InMemory(0)));
+    scoped_ptr<URLRequestJobFactoryImpl> factory(new URLRequestJobFactoryImpl);
+    factory->AddInterceptor(new CheckNoRevocationFlagSetInterceptor);
+    url_request_job_factory_ = factory.Pass();
+    set_job_factory(url_request_job_factory_.get());
+  }
+
+  virtual ~RequestContext() {
+  }
+
+ private:
+  URLRequestContextStorage storage_;
+  scoped_ptr<URLRequestJobFactory> url_request_job_factory_;
+};
+
+// Get a file:// url relative to net/data/proxy/proxy_script_fetcher_unittest.
+GURL GetTestFileUrl(const std::string& relpath) {
+  FilePath path;
+  PathService::Get(base::DIR_SOURCE_ROOT, &path);
+  path = path.AppendASCII("net");
+  path = path.AppendASCII("data");
+  path = path.AppendASCII("proxy_script_fetcher_unittest");
+  GURL base_url = FilePathToFileURL(path);
+  return GURL(base_url.spec() + "/" + relpath);
+}
+
+// Really simple NetworkDelegate so we can allow local file access on ChromeOS
+// without introducing layering violations.
+class BasicNetworkDelegate : public NetworkDelegate {
+ public:
+  BasicNetworkDelegate() {}
+  virtual ~BasicNetworkDelegate() {}
+
+ private:
+  virtual int OnBeforeURLRequest(URLRequest* request,
+                                 const CompletionCallback& callback,
+                                 GURL* new_url) OVERRIDE {
+    return OK;
+  }
+
+  virtual int OnBeforeSendHeaders(URLRequest* request,
+                                  const CompletionCallback& callback,
+                                  HttpRequestHeaders* headers) OVERRIDE {
+    return OK;
+  }
+
+  virtual void OnSendHeaders(URLRequest* request,
+                             const HttpRequestHeaders& headers) OVERRIDE {}
+
+  virtual int OnHeadersReceived(
+      URLRequest* request,
+      const CompletionCallback& callback,
+      const HttpResponseHeaders* original_response_headers,
+      scoped_refptr<HttpResponseHeaders>* override_response_headers)
+      OVERRIDE {
+    return OK;
+  }
+
+  virtual void OnBeforeRedirect(URLRequest* request,
+                                const GURL& new_location) OVERRIDE {}
+
+  virtual void OnResponseStarted(URLRequest* request) OVERRIDE {}
+
+  virtual void OnRawBytesRead(const URLRequest& request,
+                              int bytes_read) OVERRIDE {}
+
+  virtual void OnCompleted(URLRequest* request, bool started) OVERRIDE {}
+
+  virtual void OnURLRequestDestroyed(URLRequest* request) OVERRIDE {}
+
+  virtual void OnPACScriptError(int line_number,
+                                const string16& error) OVERRIDE {}
+
+  virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired(
+      URLRequest* request,
+      const AuthChallengeInfo& auth_info,
+      const AuthCallback& callback,
+      AuthCredentials* credentials) OVERRIDE {
+    return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
+  }
+
+  virtual bool OnCanGetCookies(const URLRequest& request,
+                               const CookieList& cookie_list) OVERRIDE {
+    return true;
+  }
+
+  virtual bool OnCanSetCookie(const URLRequest& request,
+                              const std::string& cookie_line,
+                              CookieOptions* options) OVERRIDE {
+    return true;
+  }
+
+  virtual bool OnCanAccessFile(const net::URLRequest& request,
+                               const FilePath& path) const OVERRIDE {
+    return true;
+  }
+  virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE {
+    return false;
+  }
+
+  virtual int OnBeforeSocketStreamConnect(
+      SocketStream* stream,
+      const CompletionCallback& callback) OVERRIDE {
+    return OK;
+  }
+
+  virtual void OnRequestWaitStateChange(const net::URLRequest& request,
+                                        RequestWaitState state) OVERRIDE {
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
+};
+
+}  // namespace
+
+class ProxyScriptFetcherImplTest : public PlatformTest {
+ public:
+  ProxyScriptFetcherImplTest()
+      : test_server_(TestServer::TYPE_HTTP,
+                     net::TestServer::kLocalhost,
+                     FilePath(kDocRoot)) {
+    context_.set_network_delegate(&network_delegate_);
+  }
+
+ protected:
+  TestServer test_server_;
+  BasicNetworkDelegate network_delegate_;
+  RequestContext context_;
+};
+
+TEST_F(ProxyScriptFetcherImplTest, FileUrl) {
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  { // Fetch a non-existent file.
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(GetTestFileUrl("does-not-exist"),
+                                   &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(ERR_FILE_NOT_FOUND, callback.WaitForResult());
+    EXPECT_TRUE(text.empty());
+  }
+  { // Fetch a file that exists.
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(GetTestFileUrl("pac.txt"),
+                                   &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
+  }
+}
+
+// Note that all mime types are allowed for PAC file, to be consistent
+// with other browsers.
+TEST_F(ProxyScriptFetcherImplTest, HttpMimeType) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  { // Fetch a PAC with mime type "text/plain"
+    GURL url(test_server_.GetURL("files/pac.txt"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
+  }
+  { // Fetch a PAC with mime type "text/html"
+    GURL url(test_server_.GetURL("files/pac.html"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-pac.html-\n"), text);
+  }
+  { // Fetch a PAC with mime type "application/x-ns-proxy-autoconfig"
+    GURL url(test_server_.GetURL("files/pac.nsproxy"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
+  }
+}
+
+TEST_F(ProxyScriptFetcherImplTest, HttpStatusCode) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  { // Fetch a PAC which gives a 500 -- FAIL
+    GURL url(test_server_.GetURL("files/500.pac"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(ERR_PAC_STATUS_NOT_OK, callback.WaitForResult());
+    EXPECT_TRUE(text.empty());
+  }
+  { // Fetch a PAC which gives a 404 -- FAIL
+    GURL url(test_server_.GetURL("files/404.pac"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(ERR_PAC_STATUS_NOT_OK, callback.WaitForResult());
+    EXPECT_TRUE(text.empty());
+  }
+}
+
+TEST_F(ProxyScriptFetcherImplTest, ContentDisposition) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  // Fetch PAC scripts via HTTP with a Content-Disposition header -- should
+  // have no effect.
+  GURL url(test_server_.GetURL("files/downloadable.pac"));
+  string16 text;
+  TestCompletionCallback callback;
+  int result = pac_fetcher.Fetch(url, &text, callback.callback());
+  EXPECT_EQ(ERR_IO_PENDING, result);
+  EXPECT_EQ(OK, callback.WaitForResult());
+  EXPECT_EQ(ASCIIToUTF16("-downloadable.pac-\n"), text);
+}
+
+// Verifies that PAC scripts are not being cached.
+TEST_F(ProxyScriptFetcherImplTest, NoCache) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  // Fetch a PAC script whose HTTP headers make it cacheable for 1 hour.
+  GURL url(test_server_.GetURL("files/cacheable_1hr.pac"));
+  {
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-cacheable_1hr.pac-\n"), text);
+  }
+
+  // Kill the HTTP server.
+  ASSERT_TRUE(test_server_.Stop());
+
+  // Try to fetch the file again. Since the server is not running anymore, the
+  // call should fail, thus indicating that the file was not fetched from the
+  // local cache.
+  {
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+
+#if defined(OS_ANDROID)
+    // On Android platform, the tests are run on the device while the server
+    // runs on the host machine. After killing the server, port forwarder
+    // running on the device is still active, which produces error message
+    // "Connection reset by peer" rather than "Connection refused".
+    EXPECT_EQ(ERR_CONNECTION_RESET, callback.WaitForResult());
+#else
+    EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
+#endif
+  }
+}
+
+TEST_F(ProxyScriptFetcherImplTest, TooLarge) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  // Set the maximum response size to 50 bytes.
+  int prev_size = pac_fetcher.SetSizeConstraint(50);
+
+  // These two URLs are the same file, but are http:// vs file://
+  GURL urls[] = {
+    test_server_.GetURL("files/large-pac.nsproxy"),
+    GetTestFileUrl("large-pac.nsproxy")
+  };
+
+  // Try fetching URLs that are 101 bytes large. We should abort the request
+  // after 50 bytes have been read, and fail with a too large error.
+  for (size_t i = 0; i < arraysize(urls); ++i) {
+    const GURL& url = urls[i];
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(ERR_FILE_TOO_BIG, callback.WaitForResult());
+    EXPECT_TRUE(text.empty());
+  }
+
+  // Restore the original size bound.
+  pac_fetcher.SetSizeConstraint(prev_size);
+
+  { // Make sure we can still fetch regular URLs.
+    GURL url(test_server_.GetURL("files/pac.nsproxy"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
+  }
+}
+
+TEST_F(ProxyScriptFetcherImplTest, Hang) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  // Set the timeout period to 0.5 seconds.
+  base::TimeDelta prev_timeout = pac_fetcher.SetTimeoutConstraint(
+      base::TimeDelta::FromMilliseconds(500));
+
+  // Try fetching a URL which takes 1.2 seconds. We should abort the request
+  // after 500 ms, and fail with a timeout error.
+  {
+    GURL url(test_server_.GetURL("slow/proxy.pac?1.2"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(ERR_TIMED_OUT, callback.WaitForResult());
+    EXPECT_TRUE(text.empty());
+  }
+
+  // Restore the original timeout period.
+  pac_fetcher.SetTimeoutConstraint(prev_timeout);
+
+  { // Make sure we can still fetch regular URLs.
+    GURL url(test_server_.GetURL("files/pac.nsproxy"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
+  }
+}
+
+// The ProxyScriptFetcher should decode any content-codings
+// (like gzip, bzip, etc.), and apply any charset conversions to yield
+// UTF8.
+TEST_F(ProxyScriptFetcherImplTest, Encodings) {
+  ASSERT_TRUE(test_server_.Start());
+
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  // Test a response that is gzip-encoded -- should get inflated.
+  {
+    GURL url(test_server_.GetURL("files/gzipped_pac"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("This data was gzipped.\n"), text);
+  }
+
+  // Test a response that was served as UTF-16 (BE). It should
+  // be converted to UTF8.
+  {
+    GURL url(test_server_.GetURL("files/utf16be_pac"));
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_IO_PENDING, result);
+    EXPECT_EQ(OK, callback.WaitForResult());
+    EXPECT_EQ(ASCIIToUTF16("This was encoded as UTF-16BE.\n"), text);
+  }
+}
+
+TEST_F(ProxyScriptFetcherImplTest, DataURLs) {
+  ProxyScriptFetcherImpl pac_fetcher(&context_);
+
+  const char kEncodedUrl[] =
+      "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R"
+      "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl"
+      "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0=";
+  const char kPacScript[] =
+      "function FindProxyForURL(url, host) {\n"
+      "  if (host == 'foobar.com')\n"
+      "    return 'PROXY blackhole:80';\n"
+      "  return 'DIRECT';\n"
+      "}";
+
+  // Test fetching a "data:"-url containing a base64 encoded PAC script.
+  {
+    GURL url(kEncodedUrl);
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(OK, result);
+    EXPECT_EQ(ASCIIToUTF16(kPacScript), text);
+  }
+
+  const char kEncodedUrlBroken[] =
+      "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R";
+
+  // Test a broken "data:"-url containing a base64 encoded PAC script.
+  {
+    GURL url(kEncodedUrlBroken);
+    string16 text;
+    TestCompletionCallback callback;
+    int result = pac_fetcher.Fetch(url, &text, callback.callback());
+    EXPECT_EQ(ERR_FAILED, result);
+  }
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_server.cc b/src/net/proxy/proxy_server.cc
new file mode 100644
index 0000000..eb160dc
--- /dev/null
+++ b/src/net/proxy/proxy_server.cc
@@ -0,0 +1,244 @@
+// Copyright (c) 2010 The Chromium Authors. 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/proxy/proxy_server.h"
+
+#include <algorithm>
+
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "net/base/net_util.h"
+#include "net/http/http_util.h"
+
+namespace net {
+
+namespace {
+
+// Parses the proxy type from a PAC string, to a ProxyServer::Scheme.
+// This mapping is case-insensitive. If no type could be matched
+// returns SCHEME_INVALID.
+ProxyServer::Scheme GetSchemeFromPacTypeInternal(
+    std::string::const_iterator begin,
+    std::string::const_iterator end) {
+  if (LowerCaseEqualsASCII(begin, end, "proxy"))
+    return ProxyServer::SCHEME_HTTP;
+  if (LowerCaseEqualsASCII(begin, end, "socks")) {
+    // Default to v4 for compatibility. This is because the SOCKS4 vs SOCKS5
+    // notation didn't originally exist, so if a client returns SOCKS they
+    // really meant SOCKS4.
+    return ProxyServer::SCHEME_SOCKS4;
+  }
+  if (LowerCaseEqualsASCII(begin, end, "socks4"))
+    return ProxyServer::SCHEME_SOCKS4;
+  if (LowerCaseEqualsASCII(begin, end, "socks5"))
+    return ProxyServer::SCHEME_SOCKS5;
+  if (LowerCaseEqualsASCII(begin, end, "direct"))
+    return ProxyServer::SCHEME_DIRECT;
+  if (LowerCaseEqualsASCII(begin, end, "https"))
+    return ProxyServer::SCHEME_HTTPS;
+
+  return ProxyServer::SCHEME_INVALID;
+}
+
+// Parses the proxy scheme from a URL-like representation, to a
+// ProxyServer::Scheme. This corresponds with the values used in
+// ProxyServer::ToURI(). If no type could be matched, returns SCHEME_INVALID.
+ProxyServer::Scheme GetSchemeFromURIInternal(std::string::const_iterator begin,
+                                             std::string::const_iterator end) {
+  if (LowerCaseEqualsASCII(begin, end, "http"))
+    return ProxyServer::SCHEME_HTTP;
+  if (LowerCaseEqualsASCII(begin, end, "socks4"))
+    return ProxyServer::SCHEME_SOCKS4;
+  if (LowerCaseEqualsASCII(begin, end, "socks"))
+    return ProxyServer::SCHEME_SOCKS5;
+  if (LowerCaseEqualsASCII(begin, end, "socks5"))
+    return ProxyServer::SCHEME_SOCKS5;
+  if (LowerCaseEqualsASCII(begin, end, "direct"))
+    return ProxyServer::SCHEME_DIRECT;
+  if (LowerCaseEqualsASCII(begin, end, "https"))
+    return ProxyServer::SCHEME_HTTPS;
+  return ProxyServer::SCHEME_INVALID;
+}
+
+std::string HostNoBrackets(const std::string& host) {
+  // Remove brackets from an RFC 2732-style IPv6 literal address.
+  const std::string::size_type len = host.size();
+  if (len >= 2 && host[0] == '[' && host[len - 1] == ']')
+    return host.substr(1, len - 2);
+  return host;
+}
+
+}  // namespace
+
+ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair)
+      : scheme_(scheme), host_port_pair_(host_port_pair) {
+  if (scheme_ == SCHEME_DIRECT || scheme_ == SCHEME_INVALID) {
+    // |host_port_pair| isn't relevant for these special schemes, so none should
+    // have been specified. It is important for this to be consistent since we
+    // do raw field comparisons in the equality and comparison functions.
+    DCHECK(host_port_pair.Equals(HostPortPair()));
+    host_port_pair_ = HostPortPair();
+  }
+}
+
+const HostPortPair& ProxyServer::host_port_pair() const {
+  // Doesn't make sense to call this if the URI scheme doesn't
+  // have concept of a host.
+  DCHECK(is_valid() && !is_direct());
+  return host_port_pair_;
+}
+
+// static
+ProxyServer ProxyServer::FromURI(const std::string& uri,
+                                 Scheme default_scheme) {
+  return FromURI(uri.begin(), uri.end(), default_scheme);
+}
+
+// static
+ProxyServer ProxyServer::FromURI(std::string::const_iterator begin,
+                                 std::string::const_iterator end,
+                                 Scheme default_scheme) {
+  // We will default to |default_scheme| if no scheme specifier was given.
+  Scheme scheme = default_scheme;
+
+  // Trim the leading/trailing whitespace.
+  HttpUtil::TrimLWS(&begin, &end);
+
+  // Check for [<scheme> "://"]
+  std::string::const_iterator colon = std::find(begin, end, ':');
+  if (colon != end &&
+      (end - colon) >= 3 &&
+      *(colon + 1) == '/' &&
+      *(colon + 2) == '/') {
+    scheme = GetSchemeFromURIInternal(begin, colon);
+    begin = colon + 3;  // Skip past the "://"
+  }
+
+  // Now parse the <host>[":"<port>].
+  return FromSchemeHostAndPort(scheme, begin, end);
+}
+
+std::string ProxyServer::ToURI() const {
+  switch (scheme_) {
+    case SCHEME_DIRECT:
+      return "direct://";
+    case SCHEME_HTTP:
+      // Leave off "http://" since it is our default scheme.
+      return host_port_pair().ToString();
+    case SCHEME_SOCKS4:
+      return std::string("socks4://") + host_port_pair().ToString();
+    case SCHEME_SOCKS5:
+      return std::string("socks5://") + host_port_pair().ToString();
+    case SCHEME_HTTPS:
+      return std::string("https://") + host_port_pair().ToString();
+    default:
+      // Got called with an invalid scheme.
+      NOTREACHED();
+      return std::string();
+  }
+}
+
+// static
+ProxyServer ProxyServer::FromPacString(const std::string& pac_string) {
+  return FromPacString(pac_string.begin(), pac_string.end());
+}
+
+// static
+ProxyServer ProxyServer::FromPacString(std::string::const_iterator begin,
+                                       std::string::const_iterator end) {
+  // Trim the leading/trailing whitespace.
+  HttpUtil::TrimLWS(&begin, &end);
+
+  // Input should match:
+  // "DIRECT" | ( <type> 1*(LWS) <host-and-port> )
+
+  // Start by finding the first space (if any).
+  std::string::const_iterator space;
+  for (space = begin; space != end; ++space) {
+    if (HttpUtil::IsLWS(*space)) {
+      break;
+    }
+  }
+
+  // Everything to the left of the space is the scheme.
+  Scheme scheme = GetSchemeFromPacTypeInternal(begin, space);
+
+  // And everything to the right of the space is the
+  // <host>[":" <port>].
+  return FromSchemeHostAndPort(scheme, space, end);
+}
+
+std::string ProxyServer::ToPacString() const {
+    switch (scheme_) {
+    case SCHEME_DIRECT:
+      return "DIRECT";
+    case SCHEME_HTTP:
+      return std::string("PROXY ") + host_port_pair().ToString();
+    case SCHEME_SOCKS4:
+      // For compatibility send SOCKS instead of SOCKS4.
+      return std::string("SOCKS ") + host_port_pair().ToString();
+    case SCHEME_SOCKS5:
+      return std::string("SOCKS5 ") + host_port_pair().ToString();
+    case SCHEME_HTTPS:
+      return std::string("HTTPS ") + host_port_pair().ToString();
+    default:
+      // Got called with an invalid scheme.
+      NOTREACHED();
+      return std::string();
+  }
+}
+
+// static
+int ProxyServer::GetDefaultPortForScheme(Scheme scheme) {
+  switch (scheme) {
+    case SCHEME_HTTP:
+      return 80;
+    case SCHEME_SOCKS4:
+    case SCHEME_SOCKS5:
+      return 1080;
+    case SCHEME_HTTPS:
+      return 443;
+    default:
+      return -1;
+  }
+}
+
+// static
+ProxyServer::Scheme ProxyServer::GetSchemeFromURI(const std::string& scheme) {
+  return GetSchemeFromURIInternal(scheme.begin(), scheme.end());
+}
+
+// static
+ProxyServer ProxyServer::FromSchemeHostAndPort(
+    Scheme scheme,
+    std::string::const_iterator begin,
+    std::string::const_iterator end) {
+
+  // Trim leading/trailing space.
+  HttpUtil::TrimLWS(&begin, &end);
+
+  if (scheme == SCHEME_DIRECT && begin != end)
+    return ProxyServer();  // Invalid -- DIRECT cannot have a host/port.
+
+  HostPortPair host_port_pair;
+
+  if (scheme != SCHEME_INVALID && scheme != SCHEME_DIRECT) {
+    std::string host;
+    int port = -1;
+    // If the scheme has a host/port, parse it.
+    bool ok = net::ParseHostAndPort(begin, end, &host, &port);
+    if (!ok)
+      return ProxyServer();  // Invalid -- failed parsing <host>[":"<port>]
+
+    // Choose a default port number if none was given.
+    if (port == -1)
+      port = GetDefaultPortForScheme(scheme);
+
+    host_port_pair = HostPortPair(HostNoBrackets(host), port);
+  }
+
+  return ProxyServer(scheme, host_port_pair);
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_server.h b/src/net/proxy/proxy_server.h
new file mode 100644
index 0000000..00cc9fd
--- /dev/null
+++ b/src/net/proxy/proxy_server.h
@@ -0,0 +1,165 @@
+// Copyright (c) 2011 The Chromium Authors. 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_PROXY_PROXY_SERVER_H_
+#define NET_PROXY_PROXY_SERVER_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_MACOSX)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#include <string>
+#include "net/base/host_port_pair.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+// ProxyServer encodes the {type, host, port} of a proxy server.
+// ProxyServer is immutable.
+class NET_EXPORT ProxyServer {
+ public:
+  // The type of proxy. These are defined as bit flags so they can be ORed
+  // together to pass as the |scheme_bit_field| argument to
+  // ProxyService::RemoveProxiesWithoutScheme().
+  enum Scheme {
+    SCHEME_INVALID = 1 << 0,
+    SCHEME_DIRECT  = 1 << 1,
+    SCHEME_HTTP    = 1 << 2,
+    SCHEME_SOCKS4  = 1 << 3,
+    SCHEME_SOCKS5  = 1 << 4,
+    SCHEME_HTTPS   = 1 << 5,
+  };
+
+  // Default copy-constructor and assignment operator are OK!
+
+  // Constructs an invalid ProxyServer.
+  ProxyServer() : scheme_(SCHEME_INVALID) {}
+
+  ProxyServer(Scheme scheme, const HostPortPair& host_port_pair);
+
+  bool is_valid() const { return scheme_ != SCHEME_INVALID; }
+
+  // Gets the proxy's scheme (i.e. SOCKS4, SOCKS5, HTTP)
+  Scheme scheme() const { return scheme_; }
+
+  // Returns true if this ProxyServer is actually just a DIRECT connection.
+  bool is_direct() const { return scheme_ == SCHEME_DIRECT; }
+
+  // Returns true if this ProxyServer is an HTTP proxy.
+  bool is_http() const { return scheme_ == SCHEME_HTTP; }
+
+  // Returns true if this ProxyServer is an HTTPS proxy.
+  bool is_https() const { return scheme_ == SCHEME_HTTPS; }
+
+  // Returns true if this ProxyServer is a SOCKS proxy.
+  bool is_socks() const {
+    return scheme_ == SCHEME_SOCKS4 || scheme_ == SCHEME_SOCKS5;
+  }
+
+  const HostPortPair& host_port_pair() const;
+
+  // Parses from an input with format:
+  //   [<scheme>"://"]<server>[":"<port>]
+  //
+  // Both <scheme> and <port> are optional. If <scheme> is omitted, it will be
+  // assumed as |default_scheme|. If <port> is omitted, it will be assumed as
+  // the default port for the chosen scheme (80 for "http", 1080 for "socks").
+  //
+  // If parsing fails the instance will be set to invalid.
+  //
+  // Examples (for |default_scheme| = SCHEME_HTTP ):
+  //   "foopy"            {scheme=HTTP, host="foopy", port=80}
+  //   "socks://foopy"    {scheme=SOCKS5, host="foopy", port=1080}
+  //   "socks4://foopy"   {scheme=SOCKS4, host="foopy", port=1080}
+  //   "socks5://foopy"   {scheme=SOCKS5, host="foopy", port=1080}
+  //   "http://foopy:17"  {scheme=HTTP, host="foopy", port=17}
+  //   "https://foopy:17" {scheme=HTTPS, host="foopy", port=17}
+  //   "direct://"        {scheme=DIRECT}
+  //   "foopy:X"          INVALID -- bad port.
+  static ProxyServer FromURI(const std::string& uri, Scheme default_scheme);
+  static ProxyServer FromURI(std::string::const_iterator uri_begin,
+                             std::string::const_iterator uri_end,
+                             Scheme default_scheme);
+
+  // Formats as a URI string. This does the reverse of FromURI.
+  std::string ToURI() const;
+
+  // Parses from a PAC string result.
+  //
+  // If <port> is omitted, it will be assumed as the default port for the
+  // chosen scheme (80 for "http", 1080 for "socks").
+  //
+  // If parsing fails the instance will be set to invalid.
+  //
+  // Examples:
+  //   "PROXY foopy:19"   {scheme=HTTP, host="foopy", port=19}
+  //   "DIRECT"           {scheme=DIRECT}
+  //   "SOCKS5 foopy"     {scheme=SOCKS5, host="foopy", port=1080}
+  //   "HTTPS foopy:123"  {scheme=HTTPS, host="foopy", port=123}
+  //   "BLAH xxx:xx"      INVALID
+  static ProxyServer FromPacString(const std::string& pac_string);
+  static ProxyServer FromPacString(std::string::const_iterator pac_string_begin,
+                                   std::string::const_iterator pac_string_end);
+
+  // Returns a ProxyServer representing DIRECT connections.
+  static ProxyServer Direct() {
+    return ProxyServer(SCHEME_DIRECT, HostPortPair());
+  }
+
+#if defined(OS_MACOSX)
+  // Utility function to pull out a host/port pair from a dictionary and return
+  // it as a ProxyServer object. Pass in a dictionary that has a  value for the
+  // host key and optionally a value for the port key. In the error condition
+  // where the host value is especially malformed, returns an invalid
+  // ProxyServer.
+  static ProxyServer FromDictionary(Scheme scheme,
+                                    CFDictionaryRef dict,
+                                    CFStringRef host_key,
+                                    CFStringRef port_key);
+#endif
+
+  // Formats as a PAC result entry. This does the reverse of FromPacString().
+  std::string ToPacString() const;
+
+  // Returns the default port number for a proxy server with the specified
+  // scheme. Returns -1 if unknown.
+  static int GetDefaultPortForScheme(Scheme scheme);
+
+  // Parses the proxy scheme from a URL-like representation, to a
+  // ProxyServer::Scheme. This corresponds with the values used in
+  // ProxyServer::ToURI(). If no type could be matched, returns SCHEME_INVALID.
+  // |scheme| can be one of http, https, socks, socks4, socks5, direct.
+  static Scheme GetSchemeFromURI(const std::string& scheme);
+
+  bool operator==(const ProxyServer& other) const {
+    return scheme_ == other.scheme_ &&
+           host_port_pair_.Equals(other.host_port_pair_);
+  }
+
+  // Comparator function so this can be placed in a std::map.
+  bool operator<(const ProxyServer& other) const {
+    if (scheme_ != other.scheme_)
+      return scheme_ < other.scheme_;
+    return host_port_pair_ < other.host_port_pair_;
+  }
+
+ private:
+  // Creates a ProxyServer given a scheme, and host/port string. If parsing the
+  // host/port string fails, the returned instance will be invalid.
+  static ProxyServer FromSchemeHostAndPort(
+      Scheme scheme,
+      std::string::const_iterator host_and_port_begin,
+      std::string::const_iterator host_and_port_end);
+
+  Scheme scheme_;
+  HostPortPair host_port_pair_;
+};
+
+typedef std::pair<HostPortPair, ProxyServer> HostPortProxyPair;
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_SERVER_H_
diff --git a/src/net/proxy/proxy_server_mac.cc b/src/net/proxy/proxy_server_mac.cc
new file mode 100644
index 0000000..b9849ff
--- /dev/null
+++ b/src/net/proxy/proxy_server_mac.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2011 The Chromium Authors. 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/proxy/proxy_server.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <string>
+
+#include "base/logging.h"
+#include "base/mac/foundation_util.h"
+#include "base/sys_string_conversions.h"
+
+namespace net {
+
+// static
+ProxyServer ProxyServer::FromDictionary(Scheme scheme,
+                                        CFDictionaryRef dict,
+                                        CFStringRef host_key,
+                                        CFStringRef port_key) {
+  if (scheme == SCHEME_INVALID || scheme == SCHEME_DIRECT) {
+    // No hostname port to extract; we are done.
+    return ProxyServer(scheme, HostPortPair());
+  }
+
+  CFStringRef host_ref =
+      base::mac::GetValueFromDictionary<CFStringRef>(dict, host_key);
+  if (!host_ref) {
+    LOG(WARNING) << "Could not find expected key "
+                 << base::SysCFStringRefToUTF8(host_key)
+                 << " in the proxy dictionary";
+    return ProxyServer();  // Invalid.
+  }
+  std::string host = base::SysCFStringRefToUTF8(host_ref);
+
+  CFNumberRef port_ref =
+      base::mac::GetValueFromDictionary<CFNumberRef>(dict, port_key);
+  int port;
+  if (port_ref) {
+    CFNumberGetValue(port_ref, kCFNumberIntType, &port);
+  } else {
+    port = GetDefaultPortForScheme(scheme);
+  }
+
+  return ProxyServer(scheme, HostPortPair(host, port));
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_server_unittest.cc b/src/net/proxy/proxy_server_unittest.cc
new file mode 100644
index 0000000..7646467
--- /dev/null
+++ b/src/net/proxy/proxy_server_unittest.cc
@@ -0,0 +1,368 @@
+// Copyright (c) 2010 The Chromium Authors. 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/basictypes.h"
+#include "net/proxy/proxy_server.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Test the creation of ProxyServer using ProxyServer::FromURI, which parses
+// inputs of the form [<scheme>"://"]<host>[":"<port>]. Verify that each part
+// was labelled correctly, and the accessors all give the right data.
+TEST(ProxyServerTest, FromURI) {
+  const struct {
+    const char* input_uri;
+    const char* expected_uri;
+    net::ProxyServer::Scheme expected_scheme;
+    const char* expected_host;
+    int expected_port;
+    const char* expected_pac_string;
+  } tests[] = {
+    // HTTP proxy URIs:
+    {
+       "foopy:10",  // No scheme.
+       "foopy:10",
+       net::ProxyServer::SCHEME_HTTP,
+       "foopy",
+       10,
+       "PROXY foopy:10"
+    },
+    {
+       "http://foopy",  // No port.
+       "foopy:80",
+       net::ProxyServer::SCHEME_HTTP,
+       "foopy",
+       80,
+       "PROXY foopy:80"
+    },
+    {
+       "http://foopy:10",
+       "foopy:10",
+       net::ProxyServer::SCHEME_HTTP,
+       "foopy",
+       10,
+       "PROXY foopy:10"
+    },
+
+    // IPv6 HTTP proxy URIs:
+    {
+       "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10",  // No scheme.
+       "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10",
+       net::ProxyServer::SCHEME_HTTP,
+       "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210",
+       10,
+       "PROXY [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:10"
+    },
+    {
+       "http://[3ffe:2a00:100:7031::1]",  // No port.
+       "[3ffe:2a00:100:7031::1]:80",
+       net::ProxyServer::SCHEME_HTTP,
+       "3ffe:2a00:100:7031::1",
+       80,
+       "PROXY [3ffe:2a00:100:7031::1]:80"
+    },
+    {
+       "http://[::192.9.5.5]",
+       "[::192.9.5.5]:80",
+       net::ProxyServer::SCHEME_HTTP,
+       "::192.9.5.5",
+       80,
+       "PROXY [::192.9.5.5]:80"
+    },
+    {
+       "http://[::FFFF:129.144.52.38]:80",
+       "[::FFFF:129.144.52.38]:80",
+       net::ProxyServer::SCHEME_HTTP,
+       "::FFFF:129.144.52.38",
+       80,
+       "PROXY [::FFFF:129.144.52.38]:80"
+    },
+
+    // SOCKS4 proxy URIs:
+    {
+       "socks4://foopy",  // No port.
+       "socks4://foopy:1080",
+       net::ProxyServer::SCHEME_SOCKS4,
+       "foopy",
+       1080,
+       "SOCKS foopy:1080"
+    },
+    {
+       "socks4://foopy:10",
+       "socks4://foopy:10",
+       net::ProxyServer::SCHEME_SOCKS4,
+       "foopy",
+       10,
+       "SOCKS foopy:10"
+    },
+
+    // SOCKS5 proxy URIs
+    {
+       "socks5://foopy",  // No port.
+       "socks5://foopy:1080",
+       net::ProxyServer::SCHEME_SOCKS5,
+       "foopy",
+       1080,
+       "SOCKS5 foopy:1080"
+    },
+    {
+       "socks5://foopy:10",
+       "socks5://foopy:10",
+       net::ProxyServer::SCHEME_SOCKS5,
+       "foopy",
+       10,
+       "SOCKS5 foopy:10"
+    },
+
+    // SOCKS proxy URIs (should default to SOCKS5)
+    {
+       "socks://foopy",  // No port.
+       "socks5://foopy:1080",
+       net::ProxyServer::SCHEME_SOCKS5,
+       "foopy",
+       1080,
+       "SOCKS5 foopy:1080"
+    },
+    {
+       "socks://foopy:10",
+       "socks5://foopy:10",
+       net::ProxyServer::SCHEME_SOCKS5,
+       "foopy",
+       10,
+       "SOCKS5 foopy:10"
+    },
+
+    // HTTPS proxy URIs:
+    {
+       "https://foopy",     // No port
+       "https://foopy:443",
+       net::ProxyServer::SCHEME_HTTPS,
+       "foopy",
+       443,
+       "HTTPS foopy:443"
+    },
+    {
+       "https://foopy:10",  // Non-standard port
+       "https://foopy:10",
+       net::ProxyServer::SCHEME_HTTPS,
+       "foopy",
+       10,
+       "HTTPS foopy:10"
+    },
+    {
+       "https://1.2.3.4:10",  // IP Address
+       "https://1.2.3.4:10",
+       net::ProxyServer::SCHEME_HTTPS,
+       "1.2.3.4",
+       10,
+       "HTTPS 1.2.3.4:10"
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    net::ProxyServer uri =
+        net::ProxyServer::FromURI(tests[i].input_uri,
+                                  net::ProxyServer::SCHEME_HTTP);
+    EXPECT_TRUE(uri.is_valid());
+    EXPECT_FALSE(uri.is_direct());
+    EXPECT_EQ(tests[i].expected_uri, uri.ToURI());
+    EXPECT_EQ(tests[i].expected_scheme, uri.scheme());
+    EXPECT_EQ(tests[i].expected_host, uri.host_port_pair().host());
+    EXPECT_EQ(tests[i].expected_port, uri.host_port_pair().port());
+    EXPECT_EQ(tests[i].expected_pac_string, uri.ToPacString());
+  }
+}
+
+TEST(ProxyServerTest, DefaultConstructor) {
+  net::ProxyServer proxy_server;
+  EXPECT_FALSE(proxy_server.is_valid());
+}
+
+// Test parsing of the special URI form "direct://". Analagous to the "DIRECT"
+// entry in a PAC result.
+TEST(ProxyServerTest, Direct) {
+  net::ProxyServer uri =
+      net::ProxyServer::FromURI("direct://", net::ProxyServer::SCHEME_HTTP);
+  EXPECT_TRUE(uri.is_valid());
+  EXPECT_TRUE(uri.is_direct());
+  EXPECT_EQ("direct://", uri.ToURI());
+  EXPECT_EQ("DIRECT", uri.ToPacString());
+}
+
+// Test parsing some invalid inputs.
+TEST(ProxyServerTest, Invalid) {
+  const char* tests[] = {
+    "",
+    "   ",
+    "dddf:",   // not a valid port
+    "dddd:d",  // not a valid port
+    "http://",  // not a valid host/port.
+    "direct://xyz",  // direct is not allowed a host/port.
+    "http:/",  // ambiguous, but will fail because of bad port.
+    "http:",  // ambiguous, but will fail because of bad port.
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    net::ProxyServer uri =
+        net::ProxyServer::FromURI(tests[i], net::ProxyServer::SCHEME_HTTP);
+    EXPECT_FALSE(uri.is_valid());
+    EXPECT_FALSE(uri.is_direct());
+    EXPECT_FALSE(uri.is_http());
+    EXPECT_FALSE(uri.is_socks());
+  }
+}
+
+// Test that LWS (SP | HT) is disregarded from the ends.
+TEST(ProxyServerTest, Whitespace) {
+  const char* tests[] = {
+    "  foopy:80",
+    "foopy:80   \t",
+    "  \tfoopy:80  ",
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    net::ProxyServer uri =
+        net::ProxyServer::FromURI(tests[i], net::ProxyServer::SCHEME_HTTP);
+    EXPECT_EQ("foopy:80", uri.ToURI());
+  }
+}
+
+// Test parsing a ProxyServer from a PAC representation.
+TEST(ProxyServerTest, FromPACString) {
+  const struct {
+    const char* input_pac;
+    const char* expected_uri;
+  } tests[] = {
+    {
+       "PROXY foopy:10",
+       "foopy:10",
+    },
+    {
+       "   PROXY    foopy:10   ",
+       "foopy:10",
+    },
+    {
+       "pRoXy foopy:10",
+       "foopy:10",
+    },
+    {
+       "PROXY foopy",  // No port.
+       "foopy:80",
+    },
+    {
+       "socks foopy",
+       "socks4://foopy:1080",
+    },
+    {
+       "socks4 foopy",
+       "socks4://foopy:1080",
+    },
+    {
+       "socks5 foopy",
+       "socks5://foopy:1080",
+    },
+    {
+       "socks5 foopy:11",
+       "socks5://foopy:11",
+    },
+    {
+       " direct  ",
+       "direct://",
+    },
+    {
+       "https foopy",
+       "https://foopy:443",
+    },
+    {
+       "https foopy:10",
+       "https://foopy:10",
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    net::ProxyServer uri = net::ProxyServer::FromPacString(tests[i].input_pac);
+    EXPECT_TRUE(uri.is_valid());
+    EXPECT_EQ(tests[i].expected_uri, uri.ToURI());
+  }
+}
+
+// Test parsing a ProxyServer from an invalid PAC representation.
+TEST(ProxyServerTest, FromPACStringInvalid) {
+  const char* tests[] = {
+    "PROXY",  // missing host/port.
+    "HTTPS",  // missing host/port.
+    "SOCKS",  // missing host/port.
+    "DIRECT foopy:10",  // direct cannot have host/port.
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    net::ProxyServer uri = net::ProxyServer::FromPacString(tests[i]);
+    EXPECT_FALSE(uri.is_valid());
+  }
+}
+
+TEST(ProxyServerTest, ComparatorAndEquality) {
+  struct {
+    // Inputs.
+    const char* server1;
+    const char* server2;
+
+    // Expectation.
+    //   -1 means server1 is less than server2
+    //    0 means server1 equals server2
+    //    1 means server1 is greater than server2
+    int expected_comparison;
+  } tests[] = {
+    { // Equal.
+      "foo:11",
+      "http://foo:11",
+      0
+    },
+    { // Port is different.
+      "foo:333",
+      "foo:444",
+      -1
+    },
+    { // Host is different.
+      "foo:33",
+      "bar:33",
+      1
+    },
+    { // Scheme is different.
+      "socks4://foo:33",
+      "http://foo:33",
+      1
+    },
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+    // Parse the expected inputs to ProxyServer instances.
+    const net::ProxyServer server1 =
+        net::ProxyServer::FromURI(
+            tests[i].server1, net::ProxyServer::SCHEME_HTTP);
+
+    const net::ProxyServer server2 =
+        net::ProxyServer::FromURI(
+            tests[i].server2, net::ProxyServer::SCHEME_HTTP);
+
+    switch (tests[i].expected_comparison) {
+      case -1:
+        EXPECT_TRUE(server1 < server2);
+        EXPECT_FALSE(server2 < server1);
+        EXPECT_FALSE(server2 == server1);
+        break;
+      case 0:
+        EXPECT_FALSE(server1 < server2);
+        EXPECT_FALSE(server2 < server1);
+        EXPECT_TRUE(server2 == server1);
+        break;
+      case 1:
+        EXPECT_FALSE(server1 < server2);
+        EXPECT_TRUE(server2 < server1);
+        EXPECT_FALSE(server2 == server1);
+        break;
+      default:
+        FAIL() << "Invalid expectation. Can be only -1, 0, 1";
+    }
+  }
+}
diff --git a/src/net/proxy/proxy_service.cc b/src/net/proxy/proxy_service.cc
new file mode 100644
index 0000000..03a053f
--- /dev/null
+++ b/src/net/proxy/proxy_service.cc
@@ -0,0 +1,1563 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_service.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "base/message_loop_proxy.h"
+#include "base/string_util.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/values.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_util.h"
+#include "net/proxy/dhcp_proxy_script_fetcher.h"
+#include "net/proxy/multi_threaded_proxy_resolver.h"
+#include "net/proxy/network_delegate_error_observer.h"
+#include "net/proxy/proxy_config_service_fixed.h"
+#include "net/proxy/proxy_resolver.h"
+#include "net/proxy/proxy_script_decider.h"
+#include "net/proxy/proxy_script_fetcher.h"
+#include "net/proxy/sync_host_resolver_bridge.h"
+#include "net/url_request/url_request_context.h"
+
+#if defined(OS_WIN)
+#include "net/proxy/proxy_config_service_win.h"
+#include "net/proxy/proxy_resolver_winhttp.h"
+#elif defined(OS_IOS)
+#include "net/proxy/proxy_config_service_ios.h"
+#include "net/proxy/proxy_resolver_mac.h"
+#elif defined(OS_MACOSX)
+#include "net/proxy/proxy_config_service_mac.h"
+#include "net/proxy/proxy_resolver_mac.h"
+#elif defined(OS_LINUX) && !defined(OS_CHROMEOS)
+#include "net/proxy/proxy_config_service_linux.h"
+#elif defined(OS_ANDROID)
+#include "net/proxy/proxy_config_service_android.h"
+#endif
+
+using base::TimeDelta;
+using base::TimeTicks;
+
+namespace net {
+
+namespace {
+
+// When the IP address changes we don't immediately re-run proxy auto-config.
+// Instead, we  wait for |kDelayAfterNetworkChangesMs| before
+// attempting to re-valuate proxy auto-config.
+//
+// During this time window, any resolve requests sent to the ProxyService will
+// be queued. Once we have waited the required amount of them, the proxy
+// auto-config step will be run, and the queued requests resumed.
+//
+// The reason we play this game is that our signal for detecting network
+// changes (NetworkChangeNotifier) may fire *before* the system's networking
+// dependencies are fully configured. This is a problem since it means if
+// we were to run proxy auto-config right away, it could fail due to spurious
+// DNS failures. (see http://crbug.com/50779 for more details.)
+//
+// By adding the wait window, we give things a better chance to get properly
+// set up. Network failures can happen at any time though, so we additionally
+// poll the PAC script for changes, which will allow us to recover from these
+// sorts of problems.
+const int64 kDelayAfterNetworkChangesMs = 2000;
+
+// This is the default policy for polling the PAC script.
+//
+// In response to a failure, the poll intervals are:
+//    0: 8 seconds  (scheduled on timer)
+//    1: 32 seconds
+//    2: 2 minutes
+//    3+: 4 hours
+//
+// In response to a success, the poll intervals are:
+//    0+: 12 hours
+//
+// Only the 8 second poll is scheduled on a timer, the rest happen in response
+// to network activity (and hence will take longer than the written time).
+//
+// Explanation for these values:
+//
+// TODO(eroman): These values are somewhat arbitrary, and need to be tuned
+// using some histograms data. Trying to be conservative so as not to break
+// existing setups when deployed. A simple exponential retry scheme would be
+// more elegant, but places more load on server.
+//
+// The motivation for trying quickly after failures (8 seconds) is to recover
+// from spurious network failures, which are common after the IP address has
+// just changed (like DNS failing to resolve). The next 32 second boundary is
+// to try and catch other VPN weirdness which anecdotally I have seen take
+// 10+ seconds for some users.
+//
+// The motivation for re-trying after a success is to check for possible
+// content changes to the script, or to the WPAD auto-discovery results. We are
+// not very aggressive with these checks so as to minimize the risk of
+// overloading existing PAC setups. Moreover it is unlikely that PAC scripts
+// change very frequently in existing setups. More research is needed to
+// motivate what safe values are here, and what other user agents do.
+//
+// Comparison to other browsers:
+//
+// In Firefox the PAC URL is re-tried on failures according to
+// network.proxy.autoconfig_retry_interval_min and
+// network.proxy.autoconfig_retry_interval_max. The defaults are 5 seconds and
+// 5 minutes respectively. It doubles the interval at each attempt.
+//
+// TODO(eroman): Figure out what Internet Explorer does.
+class DefaultPollPolicy : public ProxyService::PacPollPolicy {
+ public:
+  DefaultPollPolicy() {}
+
+  virtual Mode GetNextDelay(int initial_error,
+                            TimeDelta current_delay,
+                            TimeDelta* next_delay) const OVERRIDE {
+    if (initial_error != OK) {
+      // Re-try policy for failures.
+      const int kDelay1Seconds = 8;
+      const int kDelay2Seconds = 32;
+      const int kDelay3Seconds = 2 * 60;  // 2 minutes
+      const int kDelay4Seconds = 4 * 60 * 60;  // 4 Hours
+
+      // Initial poll.
+      if (current_delay < TimeDelta()) {
+        *next_delay = TimeDelta::FromSeconds(kDelay1Seconds);
+        return MODE_USE_TIMER;
+      }
+      switch (current_delay.InSeconds()) {
+        case kDelay1Seconds:
+          *next_delay = TimeDelta::FromSeconds(kDelay2Seconds);
+          return MODE_START_AFTER_ACTIVITY;
+        case kDelay2Seconds:
+          *next_delay = TimeDelta::FromSeconds(kDelay3Seconds);
+          return MODE_START_AFTER_ACTIVITY;
+        default:
+          *next_delay = TimeDelta::FromSeconds(kDelay4Seconds);
+          return MODE_START_AFTER_ACTIVITY;
+      }
+    } else {
+      // Re-try policy for succeses.
+      *next_delay = TimeDelta::FromHours(12);
+      return MODE_START_AFTER_ACTIVITY;
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DefaultPollPolicy);
+};
+
+// Config getter that always returns direct settings.
+class ProxyConfigServiceDirect : public ProxyConfigService {
+ public:
+  // ProxyConfigService implementation:
+  virtual void AddObserver(Observer* observer) OVERRIDE {}
+  virtual void RemoveObserver(Observer* observer) OVERRIDE {}
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config)
+      OVERRIDE {
+    *config = ProxyConfig::CreateDirect();
+    config->set_source(PROXY_CONFIG_SOURCE_UNKNOWN);
+    return CONFIG_VALID;
+  }
+};
+
+// Proxy resolver that fails every time.
+class ProxyResolverNull : public ProxyResolver {
+ public:
+  ProxyResolverNull() : ProxyResolver(false /*expects_pac_bytes*/) {}
+
+  // ProxyResolver implementation.
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE {
+    return ERR_NOT_IMPLEMENTED;
+  }
+
+  virtual void CancelRequest(RequestHandle request) OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual void CancelSetPacScript() OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& /*script_data*/,
+      const CompletionCallback& /*callback*/) OVERRIDE {
+    return ERR_NOT_IMPLEMENTED;
+  }
+};
+
+// ProxyResolver that simulates a PAC script which returns
+// |pac_string| for every single URL.
+class ProxyResolverFromPacString : public ProxyResolver {
+ public:
+  ProxyResolverFromPacString(const std::string& pac_string)
+      : ProxyResolver(false /*expects_pac_bytes*/),
+        pac_string_(pac_string) {}
+
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) OVERRIDE {
+    results->UsePacString(pac_string_);
+    return OK;
+  }
+
+  virtual void CancelRequest(RequestHandle request) OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual void CancelSetPacScript() OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& pac_script,
+      const CompletionCallback& callback) OVERRIDE {
+    return OK;
+  }
+
+ private:
+  const std::string pac_string_;
+};
+
+// Creates ProxyResolvers using a platform-specific implementation.
+class ProxyResolverFactoryForSystem : public ProxyResolverFactory {
+ public:
+  ProxyResolverFactoryForSystem()
+      : ProxyResolverFactory(false /*expects_pac_bytes*/) {}
+
+  virtual ProxyResolver* CreateProxyResolver() OVERRIDE {
+    DCHECK(IsSupported());
+#if defined(OS_WIN)
+    return new ProxyResolverWinHttp();
+#elif defined(OS_MACOSX)
+    return new ProxyResolverMac();
+#else
+    NOTREACHED();
+    return NULL;
+#endif
+  }
+
+  static bool IsSupported() {
+#if defined(OS_WIN) || defined(OS_MACOSX)
+    return true;
+#else
+    return false;
+#endif
+  }
+};
+
+// Returns NetLog parameters describing a proxy configuration change.
+Value* NetLogProxyConfigChangedCallback(const ProxyConfig* old_config,
+                                        const ProxyConfig* new_config,
+                                        NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  // The "old_config" is optional -- the first notification will not have
+  // any "previous" configuration.
+  if (old_config->is_valid())
+    dict->Set("old_config", old_config->ToValue());
+  dict->Set("new_config", new_config->ToValue());
+  return dict;
+}
+
+Value* NetLogBadProxyListCallback(const ProxyRetryInfoMap* retry_info,
+                                  NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  ListValue* list = new ListValue();
+
+  for (ProxyRetryInfoMap::const_iterator iter = retry_info->begin();
+       iter != retry_info->end(); ++iter) {
+    list->Append(Value::CreateStringValue(iter->first));
+  }
+  dict->Set("bad_proxy_list", list);
+  return dict;
+}
+
+// Returns NetLog parameters on a successfuly proxy resolution.
+Value* NetLogFinishedResolvingProxyCallback(ProxyInfo* result,
+                                            NetLog::LogLevel /* log_level */) {
+  DictionaryValue* dict = new DictionaryValue();
+  dict->SetString("pac_string", result->ToPacString());
+  return dict;
+}
+
+#if defined(OS_CHROMEOS)
+class UnsetProxyConfigService : public ProxyConfigService {
+ public:
+  UnsetProxyConfigService() {}
+  virtual ~UnsetProxyConfigService() {}
+
+  virtual void AddObserver(Observer* observer) OVERRIDE {}
+  virtual void RemoveObserver(Observer* observer) OVERRIDE {}
+  virtual ConfigAvailability GetLatestProxyConfig(
+      ProxyConfig* config) OVERRIDE {
+    return CONFIG_UNSET;
+  }
+};
+#endif
+
+}  // namespace
+
+// ProxyService::InitProxyResolver --------------------------------------------
+
+// This glues together two asynchronous steps:
+//   (1) ProxyScriptDecider -- try to fetch/validate a sequence of PAC scripts
+//       to figure out what we should configure against.
+//   (2) Feed the fetched PAC script into the ProxyResolver.
+//
+// InitProxyResolver is a single-use class which encapsulates cancellation as
+// part of its destructor. Start() or StartSkipDecider() should be called just
+// once. The instance can be destroyed at any time, and the request will be
+// cancelled.
+
+class ProxyService::InitProxyResolver {
+ public:
+  InitProxyResolver()
+      : proxy_resolver_(NULL),
+        next_state_(STATE_NONE) {
+  }
+
+  ~InitProxyResolver() {
+    // Note that the destruction of ProxyScriptDecider will automatically cancel
+    // any outstanding work.
+    if (next_state_ == STATE_SET_PAC_SCRIPT_COMPLETE) {
+      proxy_resolver_->CancelSetPacScript();
+    }
+  }
+
+  // Begins initializing the proxy resolver; calls |callback| when done.
+  int Start(ProxyResolver* proxy_resolver,
+            ProxyScriptFetcher* proxy_script_fetcher,
+            DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+            NetLog* net_log,
+            const ProxyConfig& config,
+            TimeDelta wait_delay,
+            const CompletionCallback& callback) {
+    DCHECK_EQ(STATE_NONE, next_state_);
+    proxy_resolver_ = proxy_resolver;
+
+    decider_.reset(new ProxyScriptDecider(
+        proxy_script_fetcher, dhcp_proxy_script_fetcher, net_log));
+    config_ = config;
+    wait_delay_ = wait_delay;
+    callback_ = callback;
+
+    next_state_ = STATE_DECIDE_PROXY_SCRIPT;
+    return DoLoop(OK);
+  }
+
+  // Similar to Start(), however it skips the ProxyScriptDecider stage. Instead
+  // |effective_config|, |decider_result| and |script_data| will be used as the
+  // inputs for initializing the ProxyResolver.
+  int StartSkipDecider(ProxyResolver* proxy_resolver,
+                       const ProxyConfig& effective_config,
+                       int decider_result,
+                       ProxyResolverScriptData* script_data,
+                       const CompletionCallback& callback) {
+    DCHECK_EQ(STATE_NONE, next_state_);
+    proxy_resolver_ = proxy_resolver;
+
+    effective_config_ = effective_config;
+    script_data_ = script_data;
+    callback_ = callback;
+
+    if (decider_result != OK)
+      return decider_result;
+
+    next_state_ = STATE_SET_PAC_SCRIPT;
+    return DoLoop(OK);
+  }
+
+  // Returns the proxy configuration that was selected by ProxyScriptDecider.
+  // Should only be called upon completion of the initialization.
+  const ProxyConfig& effective_config() const {
+    DCHECK_EQ(STATE_NONE, next_state_);
+    return effective_config_;
+  }
+
+  // Returns the PAC script data that was selected by ProxyScriptDecider.
+  // Should only be called upon completion of the initialization.
+  ProxyResolverScriptData* script_data() {
+    DCHECK_EQ(STATE_NONE, next_state_);
+    return script_data_.get();
+  }
+
+ private:
+  enum State {
+    STATE_NONE,
+    STATE_DECIDE_PROXY_SCRIPT,
+    STATE_DECIDE_PROXY_SCRIPT_COMPLETE,
+    STATE_SET_PAC_SCRIPT,
+    STATE_SET_PAC_SCRIPT_COMPLETE,
+  };
+
+  int DoLoop(int result) {
+    DCHECK_NE(next_state_, STATE_NONE);
+    int rv = result;
+    do {
+      State state = next_state_;
+      next_state_ = STATE_NONE;
+      switch (state) {
+        case STATE_DECIDE_PROXY_SCRIPT:
+          DCHECK_EQ(OK, rv);
+          rv = DoDecideProxyScript();
+          break;
+        case STATE_DECIDE_PROXY_SCRIPT_COMPLETE:
+          rv = DoDecideProxyScriptComplete(rv);
+          break;
+        case STATE_SET_PAC_SCRIPT:
+          DCHECK_EQ(OK, rv);
+          rv = DoSetPacScript();
+          break;
+        case STATE_SET_PAC_SCRIPT_COMPLETE:
+          rv = DoSetPacScriptComplete(rv);
+          break;
+        default:
+          NOTREACHED() << "bad state: " << state;
+          rv = ERR_UNEXPECTED;
+          break;
+      }
+    } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
+    return rv;
+  }
+
+  int DoDecideProxyScript() {
+    next_state_ = STATE_DECIDE_PROXY_SCRIPT_COMPLETE;
+
+    return decider_->Start(
+        config_, wait_delay_, proxy_resolver_->expects_pac_bytes(),
+        base::Bind(&InitProxyResolver::OnIOCompletion, base::Unretained(this)));
+  }
+
+  int DoDecideProxyScriptComplete(int result) {
+    if (result != OK)
+      return result;
+
+    effective_config_ = decider_->effective_config();
+    script_data_ = decider_->script_data();
+
+    next_state_ = STATE_SET_PAC_SCRIPT;
+    return OK;
+  }
+
+  int DoSetPacScript() {
+    DCHECK(script_data_);
+    // TODO(eroman): Should log this latency to the NetLog.
+    next_state_ = STATE_SET_PAC_SCRIPT_COMPLETE;
+    return proxy_resolver_->SetPacScript(
+        script_data_,
+        base::Bind(&InitProxyResolver::OnIOCompletion, base::Unretained(this)));
+  }
+
+  int DoSetPacScriptComplete(int result) {
+    return result;
+  }
+
+  void OnIOCompletion(int result) {
+    DCHECK_NE(STATE_NONE, next_state_);
+    int rv = DoLoop(result);
+    if (rv != ERR_IO_PENDING)
+      DoCallback(rv);
+  }
+
+  void DoCallback(int result) {
+    DCHECK_NE(ERR_IO_PENDING, result);
+    callback_.Run(result);
+  }
+
+  ProxyConfig config_;
+  ProxyConfig effective_config_;
+  scoped_refptr<ProxyResolverScriptData> script_data_;
+  TimeDelta wait_delay_;
+  scoped_ptr<ProxyScriptDecider> decider_;
+  ProxyResolver* proxy_resolver_;
+  CompletionCallback callback_;
+  State next_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(InitProxyResolver);
+};
+
+// ProxyService::ProxyScriptDeciderPoller -------------------------------------
+
+// This helper class encapsulates the logic to schedule and run periodic
+// background checks to see if the PAC script (or effective proxy configuration)
+// has changed. If a change is detected, then the caller will be notified via
+// the ChangeCallback.
+class ProxyService::ProxyScriptDeciderPoller {
+ public:
+  typedef base::Callback<void(int, ProxyResolverScriptData*,
+                              const ProxyConfig&)> ChangeCallback;
+
+  // Builds a poller helper, and starts polling for updates. Whenever a change
+  // is observed, |callback| will be invoked with the details.
+  //
+  //   |config| specifies the (unresolved) proxy configuration to poll.
+  //   |proxy_resolver_expects_pac_bytes| the type of proxy resolver we expect
+  //                                      to use the resulting script data with
+  //                                      (so it can choose the right format).
+  //   |proxy_script_fetcher| this pointer must remain alive throughout our
+  //                          lifetime. It is the dependency that will be used
+  //                          for downloading proxy scripts.
+  //   |dhcp_proxy_script_fetcher| similar to |proxy_script_fetcher|, but for
+  //                               the DHCP dependency.
+  //   |init_net_error| This is the initial network error (possibly success)
+  //                    encountered by the first PAC fetch attempt. We use it
+  //                    to schedule updates more aggressively if the initial
+  //                    fetch resulted in an error.
+  //   |init_script_data| the initial script data from the PAC fetch attempt.
+  //                      This is the baseline used to determine when the
+  //                      script's contents have changed.
+  //   |net_log| the NetLog to log progress into.
+  ProxyScriptDeciderPoller(ChangeCallback callback,
+                           const ProxyConfig& config,
+                           bool proxy_resolver_expects_pac_bytes,
+                           ProxyScriptFetcher* proxy_script_fetcher,
+                           DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+                           int init_net_error,
+                           ProxyResolverScriptData* init_script_data,
+                           NetLog* net_log)
+      : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
+        change_callback_(callback),
+        config_(config),
+        proxy_resolver_expects_pac_bytes_(proxy_resolver_expects_pac_bytes),
+        proxy_script_fetcher_(proxy_script_fetcher),
+        dhcp_proxy_script_fetcher_(dhcp_proxy_script_fetcher),
+        last_error_(init_net_error),
+        last_script_data_(init_script_data),
+        last_poll_time_(TimeTicks::Now()) {
+    // Set the initial poll delay.
+    next_poll_mode_ = poll_policy()->GetNextDelay(
+        last_error_, TimeDelta::FromSeconds(-1), &next_poll_delay_);
+    TryToStartNextPoll(false);
+  }
+
+  void OnLazyPoll() {
+    // We have just been notified of network activity. Use this opportunity to
+    // see if we can start our next poll.
+    TryToStartNextPoll(true);
+  }
+
+  static const PacPollPolicy* set_policy(const PacPollPolicy* policy) {
+    const PacPollPolicy* prev = poll_policy_;
+    poll_policy_ = policy;
+    return prev;
+  }
+
+ private:
+  // Returns the effective poll policy (the one injected by unit-tests, or the
+  // default).
+  const PacPollPolicy* poll_policy() {
+    if (poll_policy_)
+      return poll_policy_;
+    return &default_poll_policy_;
+  }
+
+  void StartPollTimer() {
+    DCHECK(!decider_.get());
+
+    MessageLoop::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&ProxyScriptDeciderPoller::DoPoll,
+                   weak_factory_.GetWeakPtr()),
+        next_poll_delay_);
+  }
+
+  void TryToStartNextPoll(bool triggered_by_activity) {
+    switch (next_poll_mode_) {
+      case PacPollPolicy::MODE_USE_TIMER:
+        if (!triggered_by_activity)
+          StartPollTimer();
+        break;
+
+      case PacPollPolicy::MODE_START_AFTER_ACTIVITY:
+        if (triggered_by_activity && !decider_.get()) {
+          TimeDelta elapsed_time = TimeTicks::Now() - last_poll_time_;
+          if (elapsed_time >= next_poll_delay_)
+            DoPoll();
+        }
+        break;
+    }
+  }
+
+  void DoPoll() {
+    last_poll_time_ = TimeTicks::Now();
+
+    // Start the proxy script decider to see if anything has changed.
+    // TODO(eroman): Pass a proper NetLog rather than NULL.
+    decider_.reset(new ProxyScriptDecider(
+        proxy_script_fetcher_, dhcp_proxy_script_fetcher_, NULL));
+    int result = decider_->Start(
+        config_, TimeDelta(), proxy_resolver_expects_pac_bytes_,
+        base::Bind(&ProxyScriptDeciderPoller::OnProxyScriptDeciderCompleted,
+                   base::Unretained(this)));
+
+    if (result != ERR_IO_PENDING)
+      OnProxyScriptDeciderCompleted(result);
+  }
+
+  void OnProxyScriptDeciderCompleted(int result) {
+    if (HasScriptDataChanged(result, decider_->script_data())) {
+      // Something has changed, we must notify the ProxyService so it can
+      // re-initialize its ProxyResolver. Note that we post a notification task
+      // rather than calling it directly -- this is done to avoid an ugly
+      // destruction sequence, since |this| might be destroyed as a result of
+      // the notification.
+      MessageLoop::current()->PostTask(
+        FROM_HERE,
+        base::Bind(
+            &ProxyScriptDeciderPoller::NotifyProxyServiceOfChange,
+            weak_factory_.GetWeakPtr(),
+            result,
+            make_scoped_refptr(decider_->script_data()),
+            decider_->effective_config()));
+      return;
+    }
+
+    decider_.reset();
+
+    // Decide when the next poll should take place, and possibly start the
+    // next timer.
+    next_poll_mode_ = poll_policy()->GetNextDelay(
+        last_error_, next_poll_delay_, &next_poll_delay_);
+    TryToStartNextPoll(false);
+  }
+
+  bool HasScriptDataChanged(int result, ProxyResolverScriptData* script_data) {
+    if (result != last_error_) {
+      // Something changed -- it was failing before and now it succeeded, or
+      // conversely it succeeded before and now it failed. Or it failed in
+      // both cases, however the specific failure error codes differ.
+      return true;
+    }
+
+    if (result != OK) {
+      // If it failed last time and failed again with the same error code this
+      // time, then nothing has actually changed.
+      return false;
+    }
+
+    // Otherwise if it succeeded both this time and last time, we need to look
+    // closer and see if we ended up downloading different content for the PAC
+    // script.
+    return !script_data->Equals(last_script_data_);
+  }
+
+  void NotifyProxyServiceOfChange(
+      int result,
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const ProxyConfig& effective_config) {
+    // Note that |this| may be deleted after calling into the ProxyService.
+    change_callback_.Run(result, script_data, effective_config);
+  }
+
+  base::WeakPtrFactory<ProxyScriptDeciderPoller> weak_factory_;
+
+  ChangeCallback change_callback_;
+  ProxyConfig config_;
+  bool proxy_resolver_expects_pac_bytes_;
+  ProxyScriptFetcher* proxy_script_fetcher_;
+  DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher_;
+
+  int last_error_;
+  scoped_refptr<ProxyResolverScriptData> last_script_data_;
+
+  scoped_ptr<ProxyScriptDecider> decider_;
+  TimeDelta next_poll_delay_;
+  PacPollPolicy::Mode next_poll_mode_;
+
+  TimeTicks last_poll_time_;
+
+  // Polling policy injected by unit-tests. Otherwise this is NULL and the
+  // default policy will be used.
+  static const PacPollPolicy* poll_policy_;
+
+  const DefaultPollPolicy default_poll_policy_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyScriptDeciderPoller);
+};
+
+// static
+const ProxyService::PacPollPolicy*
+    ProxyService::ProxyScriptDeciderPoller::poll_policy_ = NULL;
+
+// ProxyService::PacRequest ---------------------------------------------------
+
+class ProxyService::PacRequest
+    : public base::RefCounted<ProxyService::PacRequest> {
+ public:
+    PacRequest(ProxyService* service,
+             const GURL& url,
+             ProxyInfo* results,
+             const net::CompletionCallback& user_callback,
+             const BoundNetLog& net_log)
+      : service_(service),
+        user_callback_(user_callback),
+        results_(results),
+        url_(url),
+        resolve_job_(NULL),
+        config_id_(ProxyConfig::kInvalidConfigID),
+        config_source_(PROXY_CONFIG_SOURCE_UNKNOWN),
+        net_log_(net_log) {
+    DCHECK(!user_callback.is_null());
+  }
+
+  // Starts the resolve proxy request.
+  int Start() {
+    DCHECK(!was_cancelled());
+    DCHECK(!is_started());
+
+    DCHECK(service_->config_.is_valid());
+
+    config_id_ = service_->config_.id();
+    config_source_ = service_->config_.source();
+
+    return resolver()->GetProxyForURL(
+        url_, results_,
+        base::Bind(&PacRequest::QueryComplete, base::Unretained(this)),
+        &resolve_job_, net_log_);
+  }
+
+  bool is_started() const {
+    // Note that !! casts to bool. (VS gives a warning otherwise).
+    return !!resolve_job_;
+  }
+
+  void StartAndCompleteCheckingForSynchronous() {
+    int rv = service_->TryToCompleteSynchronously(url_, results_);
+    if (rv == ERR_IO_PENDING)
+      rv = Start();
+    if (rv != ERR_IO_PENDING)
+      QueryComplete(rv);
+  }
+
+  void CancelResolveJob() {
+    DCHECK(is_started());
+    // The request may already be running in the resolver.
+    resolver()->CancelRequest(resolve_job_);
+    resolve_job_ = NULL;
+    DCHECK(!is_started());
+  }
+
+  void Cancel() {
+    net_log_.AddEvent(NetLog::TYPE_CANCELLED);
+
+    if (is_started())
+      CancelResolveJob();
+
+    // Mark as cancelled, to prevent accessing this again later.
+    service_ = NULL;
+    user_callback_.Reset();
+    results_ = NULL;
+
+    net_log_.EndEvent(NetLog::TYPE_PROXY_SERVICE);
+  }
+
+  // Returns true if Cancel() has been called.
+  bool was_cancelled() const {
+    return user_callback_.is_null();
+  }
+
+  // Helper to call after ProxyResolver completion (both synchronous and
+  // asynchronous). Fixes up the result that is to be returned to user.
+  int QueryDidComplete(int result_code) {
+    DCHECK(!was_cancelled());
+
+    // Note that DidFinishResolvingProxy might modify |results_|.
+    int rv = service_->DidFinishResolvingProxy(results_, result_code, net_log_);
+
+    // Make a note in the results which configuration was in use at the
+    // time of the resolve.
+    results_->config_id_ = config_id_;
+    results_->config_source_ = config_source_;
+    results_->did_use_pac_script_ = true;
+
+    // Reset the state associated with in-progress-resolve.
+    resolve_job_ = NULL;
+    config_id_ = ProxyConfig::kInvalidConfigID;
+    config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN;
+
+    return rv;
+  }
+
+  BoundNetLog* net_log() { return &net_log_; }
+
+  LoadState GetLoadState() const {
+    if (is_started())
+      return resolver()->GetLoadState(resolve_job_);
+    return LOAD_STATE_RESOLVING_PROXY_FOR_URL;
+  }
+
+ private:
+  friend class base::RefCounted<ProxyService::PacRequest>;
+
+  ~PacRequest() {}
+
+  // Callback for when the ProxyResolver request has completed.
+  void QueryComplete(int result_code) {
+    result_code = QueryDidComplete(result_code);
+
+    // Remove this completed PacRequest from the service's pending list.
+    /// (which will probably cause deletion of |this|).
+    if (!user_callback_.is_null()){
+      net::CompletionCallback callback = user_callback_;
+      service_->RemovePendingRequest(this);
+      callback.Run(result_code);
+    }
+  }
+
+  ProxyResolver* resolver() const { return service_->resolver_.get(); }
+
+  // Note that we don't hold a reference to the ProxyService. Outstanding
+  // requests are cancelled during ~ProxyService, so this is guaranteed
+  // to be valid throughout our lifetime.
+  ProxyService* service_;
+  net::CompletionCallback user_callback_;
+  ProxyInfo* results_;
+  GURL url_;
+  ProxyResolver::RequestHandle resolve_job_;
+  ProxyConfig::ID config_id_;  // The config id when the resolve was started.
+  ProxyConfigSource config_source_;  // The source of proxy settings.
+  BoundNetLog net_log_;
+};
+
+// ProxyService ---------------------------------------------------------------
+
+ProxyService::ProxyService(ProxyConfigService* config_service,
+                           ProxyResolver* resolver,
+                           NetLog* net_log)
+    : resolver_(resolver),
+      next_config_id_(1),
+      current_state_(STATE_NONE) ,
+      net_log_(net_log),
+      stall_proxy_auto_config_delay_(TimeDelta::FromMilliseconds(
+          kDelayAfterNetworkChangesMs)) {
+  NetworkChangeNotifier::AddIPAddressObserver(this);
+  ResetConfigService(config_service);
+}
+
+// static
+ProxyService* ProxyService::CreateUsingSystemProxyResolver(
+    ProxyConfigService* proxy_config_service,
+    size_t num_pac_threads,
+    NetLog* net_log) {
+  DCHECK(proxy_config_service);
+
+  if (!ProxyResolverFactoryForSystem::IsSupported()) {
+    return CreateWithoutProxyResolver(proxy_config_service, net_log);
+  }
+
+  if (num_pac_threads == 0)
+    num_pac_threads = kDefaultNumPacThreads;
+
+  ProxyResolver* proxy_resolver = new MultiThreadedProxyResolver(
+      new ProxyResolverFactoryForSystem(), num_pac_threads);
+
+  return new ProxyService(proxy_config_service, proxy_resolver, net_log);
+}
+
+// static
+ProxyService* ProxyService::CreateWithoutProxyResolver(
+    ProxyConfigService* proxy_config_service,
+    NetLog* net_log) {
+  return new ProxyService(proxy_config_service,
+                          new ProxyResolverNull(),
+                          net_log);
+}
+
+// static
+ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) {
+  // TODO(eroman): This isn't quite right, won't work if |pc| specifies
+  //               a PAC script.
+  return CreateUsingSystemProxyResolver(new ProxyConfigServiceFixed(pc),
+                                        0, NULL);
+}
+
+// static
+ProxyService* ProxyService::CreateFixed(const std::string& proxy) {
+  net::ProxyConfig proxy_config;
+  proxy_config.proxy_rules().ParseFromString(proxy);
+  return ProxyService::CreateFixed(proxy_config);
+}
+
+// static
+ProxyService* ProxyService::CreateDirect() {
+  return CreateDirectWithNetLog(NULL);
+}
+
+ProxyService* ProxyService::CreateDirectWithNetLog(NetLog* net_log) {
+  // Use direct connections.
+  return new ProxyService(new ProxyConfigServiceDirect, new ProxyResolverNull,
+                          net_log);
+}
+
+// static
+ProxyService* ProxyService::CreateFixedFromPacResult(
+    const std::string& pac_string) {
+
+  // We need the settings to contain an "automatic" setting, otherwise the
+  // ProxyResolver dependency we give it will never be used.
+  scoped_ptr<ProxyConfigService> proxy_config_service(
+      new ProxyConfigServiceFixed(ProxyConfig::CreateAutoDetect()));
+
+  scoped_ptr<ProxyResolver> proxy_resolver(
+      new ProxyResolverFromPacString(pac_string));
+
+  return new ProxyService(proxy_config_service.release(),
+                          proxy_resolver.release(),
+                          NULL);
+}
+
+int ProxyService::ResolveProxy(const GURL& raw_url,
+                               ProxyInfo* result,
+                               const net::CompletionCallback& callback,
+                               PacRequest** pac_request,
+                               const BoundNetLog& net_log) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(!callback.is_null());
+
+  net_log.BeginEvent(NetLog::TYPE_PROXY_SERVICE);
+
+  // Notify our polling-based dependencies that a resolve is taking place.
+  // This way they can schedule their polls in response to network activity.
+  config_service_->OnLazyPoll();
+  if (script_poller_.get())
+     script_poller_->OnLazyPoll();
+
+  if (current_state_ == STATE_NONE)
+    ApplyProxyConfigIfAvailable();
+
+  // Strip away any reference fragments and the username/password, as they
+  // are not relevant to proxy resolution.
+  GURL url = SimplifyUrlForRequest(raw_url);
+
+  // Check if the request can be completed right away. (This is the case when
+  // using a direct connection for example).
+  int rv = TryToCompleteSynchronously(url, result);
+  if (rv != ERR_IO_PENDING)
+    return DidFinishResolvingProxy(result, rv, net_log);
+
+  scoped_refptr<PacRequest> req(
+      new PacRequest(this, url, result, callback, net_log));
+
+  if (current_state_ == STATE_READY) {
+    // Start the resolve request.
+    rv = req->Start();
+    if (rv != ERR_IO_PENDING)
+      return req->QueryDidComplete(rv);
+  } else {
+    req->net_log()->BeginEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC);
+  }
+
+  DCHECK_EQ(ERR_IO_PENDING, rv);
+  DCHECK(!ContainsPendingRequest(req));
+  pending_requests_.push_back(req);
+
+  // Completion will be notified through |callback|, unless the caller cancels
+  // the request using |pac_request|.
+  if (pac_request)
+    *pac_request = req.get();
+  return rv;  // ERR_IO_PENDING
+}
+
+int ProxyService::TryToCompleteSynchronously(const GURL& url,
+                                             ProxyInfo* result) {
+  DCHECK_NE(STATE_NONE, current_state_);
+
+  if (current_state_ != STATE_READY)
+    return ERR_IO_PENDING;  // Still initializing.
+
+  DCHECK_NE(config_.id(), ProxyConfig::kInvalidConfigID);
+
+  // If it was impossible to fetch or parse the PAC script, we cannot complete
+  // the request here and bail out.
+  if (permanent_error_ != OK)
+    return permanent_error_;
+
+  if (config_.HasAutomaticSettings())
+    return ERR_IO_PENDING;  // Must submit the request to the proxy resolver.
+
+  // Use the manual proxy settings.
+  config_.proxy_rules().Apply(url, result);
+  result->config_source_ = config_.source();
+  result->config_id_ = config_.id();
+  return OK;
+}
+
+ProxyService::~ProxyService() {
+  NetworkChangeNotifier::RemoveIPAddressObserver(this);
+  config_service_->RemoveObserver(this);
+
+  // Cancel any inprogress requests.
+  for (PendingRequests::iterator it = pending_requests_.begin();
+       it != pending_requests_.end();
+       ++it) {
+    (*it)->Cancel();
+  }
+}
+
+void ProxyService::SuspendAllPendingRequests() {
+  for (PendingRequests::iterator it = pending_requests_.begin();
+       it != pending_requests_.end();
+       ++it) {
+    PacRequest* req = it->get();
+    if (req->is_started()) {
+      req->CancelResolveJob();
+
+      req->net_log()->BeginEvent(
+          NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC);
+    }
+  }
+}
+
+void ProxyService::SetReady() {
+  DCHECK(!init_proxy_resolver_.get());
+  current_state_ = STATE_READY;
+
+  // Make a copy in case |this| is deleted during the synchronous completion
+  // of one of the requests. If |this| is deleted then all of the PacRequest
+  // instances will be Cancel()-ed.
+  PendingRequests pending_copy = pending_requests_;
+
+  for (PendingRequests::iterator it = pending_copy.begin();
+       it != pending_copy.end();
+       ++it) {
+    PacRequest* req = it->get();
+    if (!req->is_started() && !req->was_cancelled()) {
+      req->net_log()->EndEvent(NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC);
+
+      // Note that we re-check for synchronous completion, in case we are
+      // no longer using a ProxyResolver (can happen if we fell-back to manual).
+      req->StartAndCompleteCheckingForSynchronous();
+    }
+  }
+}
+
+void ProxyService::ApplyProxyConfigIfAvailable() {
+  DCHECK_EQ(STATE_NONE, current_state_);
+
+  config_service_->OnLazyPoll();
+
+  // If we have already fetched the configuration, start applying it.
+  if (fetched_config_.is_valid()) {
+    InitializeUsingLastFetchedConfig();
+    return;
+  }
+
+  // Otherwise we need to first fetch the configuration.
+  current_state_ = STATE_WAITING_FOR_PROXY_CONFIG;
+
+  // Retrieve the current proxy configuration from the ProxyConfigService.
+  // If a configuration is not available yet, we will get called back later
+  // by our ProxyConfigService::Observer once it changes.
+  ProxyConfig config;
+  ProxyConfigService::ConfigAvailability availability =
+      config_service_->GetLatestProxyConfig(&config);
+  if (availability != ProxyConfigService::CONFIG_PENDING)
+    OnProxyConfigChanged(config, availability);
+}
+
+void ProxyService::OnInitProxyResolverComplete(int result) {
+  DCHECK_EQ(STATE_WAITING_FOR_INIT_PROXY_RESOLVER, current_state_);
+  DCHECK(init_proxy_resolver_.get());
+  DCHECK(fetched_config_.HasAutomaticSettings());
+  config_ = init_proxy_resolver_->effective_config();
+
+  // At this point we have decided which proxy settings to use (i.e. which PAC
+  // script if any). We start up a background poller to periodically revisit
+  // this decision. If the contents of the PAC script change, or if the
+  // result of proxy auto-discovery changes, this poller will notice it and
+  // will trigger a re-initialization using the newly discovered PAC.
+  script_poller_.reset(new ProxyScriptDeciderPoller(
+      base::Bind(&ProxyService::InitializeUsingDecidedConfig,
+                 base::Unretained(this)),
+      fetched_config_,
+      resolver_->expects_pac_bytes(),
+      proxy_script_fetcher_.get(),
+      dhcp_proxy_script_fetcher_.get(),
+      result,
+      init_proxy_resolver_->script_data(),
+      NULL));
+
+  init_proxy_resolver_.reset();
+
+  if (result != OK) {
+    if (fetched_config_.pac_mandatory()) {
+      VLOG(1) << "Failed configuring with mandatory PAC script, blocking all "
+                 "traffic.";
+      config_ = fetched_config_;
+      result = ERR_MANDATORY_PROXY_CONFIGURATION_FAILED;
+    } else {
+      VLOG(1) << "Failed configuring with PAC script, falling-back to manual "
+                 "proxy servers.";
+      config_ = fetched_config_;
+      config_.ClearAutomaticSettings();
+      result = OK;
+    }
+  }
+  permanent_error_ = result;
+
+  // TODO(eroman): Make this ID unique in the case where configuration changed
+  //               due to ProxyScriptDeciderPoller.
+  config_.set_id(fetched_config_.id());
+  config_.set_source(fetched_config_.source());
+
+  // Resume any requests which we had to defer until the PAC script was
+  // downloaded.
+  SetReady();
+}
+
+int ProxyService::ReconsiderProxyAfterError(const GURL& url,
+                                            ProxyInfo* result,
+                                            const CompletionCallback& callback,
+                                            PacRequest** pac_request,
+                                            const BoundNetLog& net_log) {
+  DCHECK(CalledOnValidThread());
+
+  // Check to see if we have a new config since ResolveProxy was called.  We
+  // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a
+  // direct connection failed and we never tried the current config.
+
+  bool re_resolve = result->config_id_ != config_.id();
+
+  if (re_resolve) {
+    // If we have a new config or the config was never tried, we delete the
+    // list of bad proxies and we try again.
+    proxy_retry_info_.clear();
+    return ResolveProxy(url, result, callback, pac_request, net_log);
+  }
+
+  // We don't have new proxy settings to try, try to fallback to the next proxy
+  // in the list.
+  bool did_fallback = result->Fallback(net_log);
+
+  // Return synchronous failure if there is nothing left to fall-back to.
+  // TODO(eroman): This is a yucky API, clean it up.
+  return did_fallback ? OK : ERR_FAILED;
+}
+
+bool ProxyService::MarkProxyAsBad(const ProxyInfo& result,
+                                  const BoundNetLog& net_log) {
+  result.proxy_list_.UpdateRetryInfoOnFallback(&proxy_retry_info_, net_log);
+  return result.proxy_list_.HasUntriedProxies(proxy_retry_info_);
+}
+
+void ProxyService::ReportSuccess(const ProxyInfo& result) {
+  DCHECK(CalledOnValidThread());
+
+  const ProxyRetryInfoMap& new_retry_info = result.proxy_retry_info();
+  if (new_retry_info.empty())
+    return;
+
+  for (ProxyRetryInfoMap::const_iterator iter = new_retry_info.begin();
+       iter != new_retry_info.end(); ++iter) {
+    ProxyRetryInfoMap::iterator existing = proxy_retry_info_.find(iter->first);
+    if (existing == proxy_retry_info_.end())
+      proxy_retry_info_[iter->first] = iter->second;
+    else if (existing->second.bad_until < iter->second.bad_until)
+      existing->second.bad_until = iter->second.bad_until;
+  }
+  if (net_log_) {
+    net_log_->AddGlobalEntry(
+        NetLog::TYPE_BAD_PROXY_LIST_REPORTED,
+        base::Bind(&NetLogBadProxyListCallback, &new_retry_info));
+  }
+}
+
+void ProxyService::CancelPacRequest(PacRequest* req) {
+  DCHECK(CalledOnValidThread());
+  DCHECK(req);
+  req->Cancel();
+  RemovePendingRequest(req);
+}
+
+LoadState ProxyService::GetLoadState(const PacRequest* req) const {
+  CHECK(req);
+  return req->GetLoadState();
+}
+
+bool ProxyService::ContainsPendingRequest(PacRequest* req) {
+  PendingRequests::iterator it = std::find(
+      pending_requests_.begin(), pending_requests_.end(), req);
+  return pending_requests_.end() != it;
+}
+
+void ProxyService::RemovePendingRequest(PacRequest* req) {
+  DCHECK(ContainsPendingRequest(req));
+  PendingRequests::iterator it = std::find(
+      pending_requests_.begin(), pending_requests_.end(), req);
+  pending_requests_.erase(it);
+}
+
+int ProxyService::DidFinishResolvingProxy(ProxyInfo* result,
+                                          int result_code,
+                                          const BoundNetLog& net_log) {
+  // Log the result of the proxy resolution.
+  if (result_code == OK) {
+    // When logging all events is enabled, dump the proxy list.
+    if (net_log.IsLoggingAllEvents()) {
+      net_log.AddEvent(
+          NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
+          base::Bind(&NetLogFinishedResolvingProxyCallback, result));
+    }
+    result->DeprioritizeBadProxies(proxy_retry_info_);
+  } else {
+    net_log.AddEventWithNetErrorCode(
+        NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST, result_code);
+
+    if (!config_.pac_mandatory()) {
+      // Fall-back to direct when the proxy resolver fails. This corresponds
+      // with a javascript runtime error in the PAC script.
+      //
+      // This implicit fall-back to direct matches Firefox 3.5 and
+      // Internet Explorer 8. For more information, see:
+      //
+      // http://www.chromium.org/developers/design-documents/proxy-settings-fallback
+      result->UseDirect();
+      result_code = OK;
+    } else {
+      result_code = ERR_MANDATORY_PROXY_CONFIGURATION_FAILED;
+    }
+  }
+
+  net_log.EndEvent(NetLog::TYPE_PROXY_SERVICE);
+  return result_code;
+}
+
+void ProxyService::SetProxyScriptFetchers(
+    ProxyScriptFetcher* proxy_script_fetcher,
+    DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher) {
+  DCHECK(CalledOnValidThread());
+  State previous_state = ResetProxyConfig(false);
+  proxy_script_fetcher_.reset(proxy_script_fetcher);
+  dhcp_proxy_script_fetcher_.reset(dhcp_proxy_script_fetcher);
+  if (previous_state != STATE_NONE)
+    ApplyProxyConfigIfAvailable();
+}
+
+ProxyScriptFetcher* ProxyService::GetProxyScriptFetcher() const {
+  DCHECK(CalledOnValidThread());
+  return proxy_script_fetcher_.get();
+}
+
+ProxyService::State ProxyService::ResetProxyConfig(bool reset_fetched_config) {
+  DCHECK(CalledOnValidThread());
+  State previous_state = current_state_;
+
+  permanent_error_ = OK;
+  proxy_retry_info_.clear();
+  script_poller_.reset();
+  init_proxy_resolver_.reset();
+  SuspendAllPendingRequests();
+  config_ = ProxyConfig();
+  if (reset_fetched_config)
+    fetched_config_ = ProxyConfig();
+  current_state_ = STATE_NONE;
+
+  return previous_state;
+}
+
+void ProxyService::ResetConfigService(
+    ProxyConfigService* new_proxy_config_service) {
+  DCHECK(CalledOnValidThread());
+  State previous_state = ResetProxyConfig(true);
+
+  // Release the old configuration service.
+  if (config_service_.get())
+    config_service_->RemoveObserver(this);
+
+  // Set the new configuration service.
+  config_service_.reset(new_proxy_config_service);
+  config_service_->AddObserver(this);
+
+  if (previous_state != STATE_NONE)
+    ApplyProxyConfigIfAvailable();
+}
+
+void ProxyService::PurgeMemory() {
+  DCHECK(CalledOnValidThread());
+  if (resolver_.get())
+    resolver_->PurgeMemory();
+}
+
+void ProxyService::ForceReloadProxyConfig() {
+  DCHECK(CalledOnValidThread());
+  ResetProxyConfig(false);
+  ApplyProxyConfigIfAvailable();
+}
+
+// static
+ProxyConfigService* ProxyService::CreateSystemProxyConfigService(
+    base::SingleThreadTaskRunner* io_thread_task_runner,
+    MessageLoop* file_loop) {
+#if defined(OS_WIN)
+  return new ProxyConfigServiceWin();
+#elif defined(OS_IOS)
+  return new ProxyConfigServiceIOS();
+#elif defined(OS_MACOSX)
+  return new ProxyConfigServiceMac(io_thread_task_runner);
+#elif defined(OS_CHROMEOS)
+  LOG(ERROR) << "ProxyConfigService for ChromeOS should be created in "
+             << "profile_io_data.cc::CreateProxyConfigService and this should "
+             << "be used only for examples.";
+  return new UnsetProxyConfigService;
+#elif defined(OS_LINUX)
+  ProxyConfigServiceLinux* linux_config_service =
+      new ProxyConfigServiceLinux();
+
+  // Assume we got called on the thread that runs the default glib
+  // main loop, so the current thread is where we should be running
+  // gconf calls from.
+  scoped_refptr<base::SingleThreadTaskRunner> glib_thread_task_runner =
+      base::ThreadTaskRunnerHandle::Get();
+
+  // The file loop should be a MessageLoopForIO on Linux.
+  DCHECK_EQ(MessageLoop::TYPE_IO, file_loop->type());
+
+  // Synchronously fetch the current proxy config (since we are
+  // running on glib_default_loop). Additionally register for
+  // notifications (delivered in either |glib_default_loop| or
+  // |file_loop|) to keep us updated when the proxy config changes.
+  linux_config_service->SetupAndFetchInitialConfig(
+      glib_thread_task_runner, io_thread_task_runner,
+      static_cast<MessageLoopForIO*>(file_loop));
+
+  return linux_config_service;
+#elif defined(OS_ANDROID)
+  return new ProxyConfigServiceAndroid(
+      io_thread_task_runner,
+      MessageLoop::current()->message_loop_proxy());
+#elif defined(__LB_SHELL__)
+  // Only reachable in unit tests.
+  return new ProxyConfigServiceDirect();
+#else
+  LOG(WARNING) << "Failed to choose a system proxy settings fetcher "
+                  "for this platform.";
+  return new ProxyConfigServiceDirect();
+#endif
+}
+
+// static
+const ProxyService::PacPollPolicy* ProxyService::set_pac_script_poll_policy(
+    const PacPollPolicy* policy) {
+  return ProxyScriptDeciderPoller::set_policy(policy);
+}
+
+// static
+scoped_ptr<ProxyService::PacPollPolicy>
+  ProxyService::CreateDefaultPacPollPolicy() {
+  return scoped_ptr<PacPollPolicy>(new DefaultPollPolicy());
+}
+
+void ProxyService::OnProxyConfigChanged(
+    const ProxyConfig& config,
+    ProxyConfigService::ConfigAvailability availability) {
+  // Retrieve the current proxy configuration from the ProxyConfigService.
+  // If a configuration is not available yet, we will get called back later
+  // by our ProxyConfigService::Observer once it changes.
+  ProxyConfig effective_config;
+  switch (availability) {
+    case ProxyConfigService::CONFIG_PENDING:
+      // ProxyConfigService implementors should never pass CONFIG_PENDING.
+      NOTREACHED() << "Proxy config change with CONFIG_PENDING availability!";
+      return;
+    case ProxyConfigService::CONFIG_VALID:
+      effective_config = config;
+      break;
+    case ProxyConfigService::CONFIG_UNSET:
+      effective_config = ProxyConfig::CreateDirect();
+      break;
+  }
+
+  // Emit the proxy settings change to the NetLog stream.
+  if (net_log_) {
+    net_log_->AddGlobalEntry(
+        net::NetLog::TYPE_PROXY_CONFIG_CHANGED,
+        base::Bind(&NetLogProxyConfigChangedCallback,
+                   &fetched_config_, &effective_config));
+  }
+
+  // Set the new configuration as the most recently fetched one.
+  fetched_config_ = effective_config;
+  fetched_config_.set_id(1);  // Needed for a later DCHECK of is_valid().
+
+  InitializeUsingLastFetchedConfig();
+}
+
+void ProxyService::InitializeUsingLastFetchedConfig() {
+  ResetProxyConfig(false);
+
+  DCHECK(fetched_config_.is_valid());
+
+  // Increment the ID to reflect that the config has changed.
+  fetched_config_.set_id(next_config_id_++);
+
+  if (!fetched_config_.HasAutomaticSettings()) {
+    config_ = fetched_config_;
+    SetReady();
+    return;
+  }
+
+  // Start downloading + testing the PAC scripts for this new configuration.
+  current_state_ = STATE_WAITING_FOR_INIT_PROXY_RESOLVER;
+
+  // If we changed networks recently, we should delay running proxy auto-config.
+  TimeDelta wait_delay =
+      stall_proxy_autoconfig_until_ - TimeTicks::Now();
+
+  init_proxy_resolver_.reset(new InitProxyResolver());
+  int rv = init_proxy_resolver_->Start(
+      resolver_.get(),
+      proxy_script_fetcher_.get(),
+      dhcp_proxy_script_fetcher_.get(),
+      net_log_,
+      fetched_config_,
+      wait_delay,
+      base::Bind(&ProxyService::OnInitProxyResolverComplete,
+                 base::Unretained(this)));
+
+  if (rv != ERR_IO_PENDING)
+    OnInitProxyResolverComplete(rv);
+}
+
+void ProxyService::InitializeUsingDecidedConfig(
+    int decider_result,
+    ProxyResolverScriptData* script_data,
+    const ProxyConfig& effective_config) {
+  DCHECK(fetched_config_.is_valid());
+  DCHECK(fetched_config_.HasAutomaticSettings());
+
+  ResetProxyConfig(false);
+
+  current_state_ = STATE_WAITING_FOR_INIT_PROXY_RESOLVER;
+
+  init_proxy_resolver_.reset(new InitProxyResolver());
+  int rv = init_proxy_resolver_->StartSkipDecider(
+      resolver_.get(),
+      effective_config,
+      decider_result,
+      script_data,
+      base::Bind(&ProxyService::OnInitProxyResolverComplete,
+                 base::Unretained(this)));
+
+  if (rv != ERR_IO_PENDING)
+    OnInitProxyResolverComplete(rv);
+}
+
+void ProxyService::OnIPAddressChanged() {
+  // See the comment block by |kDelayAfterNetworkChangesMs| for info.
+  stall_proxy_autoconfig_until_ =
+      TimeTicks::Now() + stall_proxy_auto_config_delay_;
+
+  State previous_state = ResetProxyConfig(false);
+  if (previous_state != STATE_NONE)
+    ApplyProxyConfigIfAvailable();
+}
+
+SyncProxyServiceHelper::SyncProxyServiceHelper(MessageLoop* io_message_loop,
+                                               ProxyService* proxy_service)
+    : io_message_loop_(io_message_loop),
+      proxy_service_(proxy_service),
+      event_(false, false),
+      ALLOW_THIS_IN_INITIALIZER_LIST(callback_(
+          base::Bind(&SyncProxyServiceHelper::OnCompletion,
+                     base::Unretained(this)))) {
+  DCHECK(io_message_loop_ != MessageLoop::current());
+}
+
+int SyncProxyServiceHelper::ResolveProxy(const GURL& url,
+                                         ProxyInfo* proxy_info,
+                                         const BoundNetLog& net_log) {
+  DCHECK(io_message_loop_ != MessageLoop::current());
+
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&SyncProxyServiceHelper::StartAsyncResolve, this, url,
+                 net_log));
+
+  event_.Wait();
+
+  if (result_ == net::OK) {
+    *proxy_info = proxy_info_;
+  }
+  return result_;
+}
+
+int SyncProxyServiceHelper::ReconsiderProxyAfterError(
+    const GURL& url, ProxyInfo* proxy_info, const BoundNetLog& net_log) {
+  DCHECK(io_message_loop_ != MessageLoop::current());
+
+  io_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&SyncProxyServiceHelper::StartAsyncReconsider, this, url,
+                 net_log));
+
+  event_.Wait();
+
+  if (result_ == net::OK) {
+    *proxy_info = proxy_info_;
+  }
+  return result_;
+}
+
+SyncProxyServiceHelper::~SyncProxyServiceHelper() {}
+
+void SyncProxyServiceHelper::StartAsyncResolve(const GURL& url,
+                                               const BoundNetLog& net_log) {
+  result_ = proxy_service_->ResolveProxy(
+      url, &proxy_info_, callback_, NULL, net_log);
+  if (result_ != net::ERR_IO_PENDING) {
+    OnCompletion(result_);
+  }
+}
+
+void SyncProxyServiceHelper::StartAsyncReconsider(const GURL& url,
+                                                  const BoundNetLog& net_log) {
+  result_ = proxy_service_->ReconsiderProxyAfterError(
+      url, &proxy_info_, callback_, NULL, net_log);
+  if (result_ != net::ERR_IO_PENDING) {
+    OnCompletion(result_);
+  }
+}
+
+void SyncProxyServiceHelper::OnCompletion(int rv) {
+  result_ = rv;
+  event_.Signal();
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_service.h b/src/net/proxy/proxy_service.h
new file mode 100644
index 0000000..500d2a1
--- /dev/null
+++ b/src/net/proxy/proxy_service.h
@@ -0,0 +1,436 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_PROXY_SERVICE_H_
+#define NET_PROXY_PROXY_SERVICE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/non_thread_safe.h"
+#include "net/base/completion_callback.h"
+#include "net/base/load_states.h"
+#include "net/base/net_export.h"
+#include "net/base/net_log.h"
+#include "net/base/network_change_notifier.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_server.h"
+
+class GURL;
+class MessageLoop;
+
+namespace base {
+class SingleThreadTaskRunner;
+}  // namespace base
+
+namespace net {
+
+class DhcpProxyScriptFetcher;
+class HostResolver;
+class NetworkDelegate;
+class ProxyResolver;
+class ProxyResolverScriptData;
+class ProxyScriptDecider;
+class ProxyScriptFetcher;
+
+// This class can be used to resolve the proxy server to use when loading a
+// HTTP(S) URL.  It uses the given ProxyResolver to handle the actual proxy
+// resolution.  See ProxyResolverV8 for example.
+class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver,
+                                public ProxyConfigService::Observer,
+                                NON_EXPORTED_BASE(public base::NonThreadSafe) {
+ public:
+  static const size_t kDefaultNumPacThreads = 4;
+
+  // This interface defines the set of policies for when to poll the PAC
+  // script for changes.
+  //
+  // The polling policy decides what the next poll delay should be in
+  // milliseconds. It also decides how to wait for this delay -- either
+  // by starting a timer to do the poll at exactly |next_delay_ms|
+  // (MODE_USE_TIMER) or by waiting for the first network request issued after
+  // |next_delay_ms| (MODE_START_AFTER_ACTIVITY).
+  //
+  // The timer method is more precise and guarantees that polling happens when
+  // it was requested. However it has the disadvantage of causing spurious CPU
+  // and network activity. It is a reasonable choice to use for short poll
+  // intervals which only happen a couple times.
+  //
+  // However for repeated timers this will prevent the browser from going
+  // idle. MODE_START_AFTER_ACTIVITY solves this problem by only polling in
+  // direct response to network activity. The drawback to
+  // MODE_START_AFTER_ACTIVITY is since the poll is initiated only after the
+  // request is received, the first couple requests initiated after a long
+  // period of inactivity will likely see a stale version of the PAC script
+  // until the background polling gets a chance to update things.
+  class NET_EXPORT_PRIVATE PacPollPolicy {
+   public:
+    enum Mode {
+      MODE_USE_TIMER,
+      MODE_START_AFTER_ACTIVITY,
+    };
+
+    virtual ~PacPollPolicy() {}
+
+    // Decides the next poll delay. |current_delay| is the delay used
+    // by the preceding poll, or a negative TimeDelta value if determining
+    // the delay for the initial poll. |initial_error| is the network error
+    // code that the last PAC fetch (or WPAD initialization) failed with,
+    // or OK if it completed successfully. Implementations must set
+    // |next_delay| to a non-negative value.
+    virtual Mode GetNextDelay(int initial_error,
+                              base::TimeDelta current_delay,
+                              base::TimeDelta* next_delay) const = 0;
+  };
+
+  // The instance takes ownership of |config_service| and |resolver|.
+  // |net_log| is a possibly NULL destination to send log events to. It must
+  // remain alive for the lifetime of this ProxyService.
+  ProxyService(ProxyConfigService* config_service,
+               ProxyResolver* resolver,
+               NetLog* net_log);
+
+  virtual ~ProxyService();
+
+  // Used internally to handle PAC queries.
+  // TODO(eroman): consider naming this simply "Request".
+  class PacRequest;
+
+  // Returns ERR_IO_PENDING if the proxy information could not be provided
+  // synchronously, to indicate that the result will be available when the
+  // callback is run.  The callback is run on the thread that calls
+  // ResolveProxy.
+  //
+  // The caller is responsible for ensuring that |results| and |callback|
+  // remain valid until the callback is run or until |pac_request| is cancelled
+  // via CancelPacRequest.  |pac_request| is only valid while the completion
+  // callback is still pending. NULL can be passed for |pac_request| if
+  // the caller will not need to cancel the request.
+  //
+  // We use the three possible proxy access types in the following order,
+  // doing fallback if one doesn't work.  See "pac_script_decider.h"
+  // for the specifics.
+  //   1.  WPAD auto-detection
+  //   2.  PAC URL
+  //   3.  named proxy
+  //
+  // Profiling information for the request is saved to |net_log| if non-NULL.
+  int ResolveProxy(const GURL& url,
+                   ProxyInfo* results,
+                   const net::CompletionCallback& callback,
+                   PacRequest** pac_request,
+                   const BoundNetLog& net_log);
+
+  // This method is called after a failure to connect or resolve a host name.
+  // It gives the proxy service an opportunity to reconsider the proxy to use.
+  // The |results| parameter contains the results returned by an earlier call
+  // to ResolveProxy.  The semantics of this call are otherwise similar to
+  // ResolveProxy.
+  //
+  // NULL can be passed for |pac_request| if the caller will not need to
+  // cancel the request.
+  //
+  // Returns ERR_FAILED if there is not another proxy config to try.
+  //
+  // Profiling information for the request is saved to |net_log| if non-NULL.
+  int ReconsiderProxyAfterError(const GURL& url,
+                                ProxyInfo* results,
+                                const CompletionCallback& callback,
+                                PacRequest** pac_request,
+                                const BoundNetLog& net_log);
+
+  // Explicitly trigger proxy fallback for the given |results| by updating our
+  // list of bad proxies to include the first entry of |results|. Returns true
+  // if there will be at least one proxy remaining in the list after fallback
+  // and false otherwise.
+  bool MarkProxyAsBad(const ProxyInfo& results, const BoundNetLog& net_log);
+
+  // Called to report that the last proxy connection succeeded.  If |proxy_info|
+  // has a non empty proxy_retry_info map, the proxies that have been tried (and
+  // failed) for this request will be marked as bad.
+  void ReportSuccess(const ProxyInfo& proxy_info);
+
+  // Call this method with a non-null |pac_request| to cancel the PAC request.
+  void CancelPacRequest(PacRequest* pac_request);
+
+  // Returns the LoadState for this |pac_request| which must be non-NULL.
+  LoadState GetLoadState(const PacRequest* pac_request) const;
+
+  // Sets the ProxyScriptFetcher and DhcpProxyScriptFetcher dependencies. This
+  // is needed if the ProxyResolver is of type ProxyResolverWithoutFetch.
+  // ProxyService takes ownership of both objects.
+  void SetProxyScriptFetchers(
+      ProxyScriptFetcher* proxy_script_fetcher,
+      DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher);
+  ProxyScriptFetcher* GetProxyScriptFetcher() const;
+
+  // Tells this ProxyService to start using a new ProxyConfigService to
+  // retrieve its ProxyConfig from. The new ProxyConfigService will immediately
+  // be queried for new config info which will be used for all subsequent
+  // ResolveProxy calls. ProxyService takes ownership of
+  // |new_proxy_config_service|.
+  void ResetConfigService(ProxyConfigService* new_proxy_config_service);
+
+  // Tells the resolver to purge any memory it does not need.
+  void PurgeMemory();
+
+
+  // Returns the last configuration fetched from ProxyConfigService.
+  const ProxyConfig& fetched_config() {
+    return fetched_config_;
+  }
+
+  // Returns the current configuration being used by ProxyConfigService.
+  const ProxyConfig& config() {
+    return config_;
+  }
+
+  // Returns the map of proxies which have been marked as "bad".
+  const ProxyRetryInfoMap& proxy_retry_info() const {
+    return proxy_retry_info_;
+  }
+
+  // Clears the list of bad proxy servers that has been cached.
+  void ClearBadProxiesCache() {
+    proxy_retry_info_.clear();
+  }
+
+  // Forces refetching the proxy configuration, and applying it.
+  // This re-does everything from fetching the system configuration,
+  // to downloading and testing the PAC files.
+  void ForceReloadProxyConfig();
+
+  // Same as CreateProxyServiceUsingV8ProxyResolver, except it uses system
+  // libraries for evaluating the PAC script if available, otherwise skips
+  // proxy autoconfig.
+  static ProxyService* CreateUsingSystemProxyResolver(
+      ProxyConfigService* proxy_config_service,
+      size_t num_pac_threads,
+      NetLog* net_log);
+
+  // Creates a ProxyService without support for proxy autoconfig.
+  static ProxyService* CreateWithoutProxyResolver(
+      ProxyConfigService* proxy_config_service,
+      NetLog* net_log);
+
+  // Convenience methods that creates a proxy service using the
+  // specified fixed settings.
+  static ProxyService* CreateFixed(const ProxyConfig& pc);
+  static ProxyService* CreateFixed(const std::string& proxy);
+
+  // Creates a proxy service that uses a DIRECT connection for all requests.
+  static ProxyService* CreateDirect();
+  // |net_log|'s lifetime must exceed ProxyService.
+  static ProxyService* CreateDirectWithNetLog(NetLog* net_log);
+
+  // This method is used by tests to create a ProxyService that returns a
+  // hardcoded proxy fallback list (|pac_string|) for every URL.
+  //
+  // |pac_string| is a list of proxy servers, in the format that a PAC script
+  // would return it. For example, "PROXY foobar:99; SOCKS fml:2; DIRECT"
+  static ProxyService* CreateFixedFromPacResult(const std::string& pac_string);
+
+  // Creates a config service appropriate for this platform that fetches the
+  // system proxy settings.
+  static ProxyConfigService* CreateSystemProxyConfigService(
+      base::SingleThreadTaskRunner* io_thread_task_runner,
+      MessageLoop* file_loop);
+
+  // This method should only be used by unit tests.
+  void set_stall_proxy_auto_config_delay(base::TimeDelta delay) {
+    stall_proxy_auto_config_delay_ = delay;
+  }
+
+  // This method should only be used by unit tests. Returns the previously
+  // active policy.
+  static const PacPollPolicy* set_pac_script_poll_policy(
+      const PacPollPolicy* policy);
+
+  // This method should only be used by unit tests. Creates an instance
+  // of the default internal PacPollPolicy used by ProxyService.
+  static scoped_ptr<PacPollPolicy> CreateDefaultPacPollPolicy();
+
+ private:
+  FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigAfterFailedAutodetect);
+  FRIEND_TEST_ALL_PREFIXES(ProxyServiceTest, UpdateConfigFromPACToDirect);
+  friend class PacRequest;
+  class InitProxyResolver;
+  class ProxyScriptDeciderPoller;
+
+  // TODO(eroman): change this to a std::set. Note that this requires updating
+  // some tests in proxy_service_unittest.cc such as:
+  //   ProxyServiceTest.InitialPACScriptDownload
+  // which expects requests to finish in the order they were added.
+  typedef std::vector<scoped_refptr<PacRequest> > PendingRequests;
+
+  enum State {
+    STATE_NONE,
+    STATE_WAITING_FOR_PROXY_CONFIG,
+    STATE_WAITING_FOR_INIT_PROXY_RESOLVER,
+    STATE_READY,
+  };
+
+  // Resets all the variables associated with the current proxy configuration,
+  // and rewinds the current state to |STATE_NONE|. Returns the previous value
+  // of |current_state_|.  If |reset_fetched_config| is true then
+  // |fetched_config_| will also be reset, otherwise it will be left as-is.
+  // Resetting it means that we will have to re-fetch the configuration from
+  // the ProxyConfigService later.
+  State ResetProxyConfig(bool reset_fetched_config);
+
+  // Retrieves the current proxy configuration from the ProxyConfigService, and
+  // starts initializing for it.
+  void ApplyProxyConfigIfAvailable();
+
+  // Callback for when the proxy resolver has been initialized with a
+  // PAC script.
+  void OnInitProxyResolverComplete(int result);
+
+  // Returns ERR_IO_PENDING if the request cannot be completed synchronously.
+  // Otherwise it fills |result| with the proxy information for |url|.
+  // Completing synchronously means we don't need to query ProxyResolver.
+  int TryToCompleteSynchronously(const GURL& url, ProxyInfo* result);
+
+  // Cancels all of the requests sent to the ProxyResolver. These will be
+  // restarted when calling ResumeAllPendingRequests().
+  void SuspendAllPendingRequests();
+
+  // Advances the current state to |STATE_READY|, and resumes any pending
+  // requests which had been stalled waiting for initialization to complete.
+  void SetReady();
+
+  // Returns true if |pending_requests_| contains |req|.
+  bool ContainsPendingRequest(PacRequest* req);
+
+  // Removes |req| from the list of pending requests.
+  void RemovePendingRequest(PacRequest* req);
+
+  // Called when proxy resolution has completed (either synchronously or
+  // asynchronously). Handles logging the result, and cleaning out
+  // bad entries from the results list.
+  int DidFinishResolvingProxy(ProxyInfo* result,
+                              int result_code,
+                              const BoundNetLog& net_log);
+
+  // Start initialization using |fetched_config_|.
+  void InitializeUsingLastFetchedConfig();
+
+  // Start the initialization skipping past the "decision" phase.
+  void InitializeUsingDecidedConfig(
+      int decider_result,
+      ProxyResolverScriptData* script_data,
+      const ProxyConfig& effective_config);
+
+  // NetworkChangeNotifier::IPAddressObserver
+  // When this is called, we re-fetch PAC scripts and re-run WPAD.
+  virtual void OnIPAddressChanged() OVERRIDE;
+
+  // ProxyConfigService::Observer
+  virtual void OnProxyConfigChanged(
+      const ProxyConfig& config,
+      ProxyConfigService::ConfigAvailability availability) OVERRIDE;
+
+  scoped_ptr<ProxyConfigService> config_service_;
+  scoped_ptr<ProxyResolver> resolver_;
+
+  // We store the proxy configuration that was last fetched from the
+  // ProxyConfigService, as well as the resulting "effective" configuration.
+  // The effective configuration is what we condense the original fetched
+  // settings to after testing the various automatic settings (auto-detect
+  // and custom PAC url).
+  ProxyConfig fetched_config_;
+  ProxyConfig config_;
+
+  // Increasing ID to give to the next ProxyConfig that we set.
+  int next_config_id_;
+
+  // The time when the proxy configuration was last read from the system.
+  base::TimeTicks config_last_update_time_;
+
+  // Map of the known bad proxies and the information about the retry time.
+  ProxyRetryInfoMap proxy_retry_info_;
+
+  // Set of pending/inprogress requests.
+  PendingRequests pending_requests_;
+
+  // The fetcher to use when downloading PAC scripts for the ProxyResolver.
+  // This dependency can be NULL if our ProxyResolver has no need for
+  // external PAC script fetching.
+  scoped_ptr<ProxyScriptFetcher> proxy_script_fetcher_;
+
+  // The fetcher to use when attempting to download the most appropriate PAC
+  // script configured in DHCP, if any. Can be NULL if the ProxyResolver has
+  // no need for DHCP PAC script fetching.
+  scoped_ptr<DhcpProxyScriptFetcher> dhcp_proxy_script_fetcher_;
+
+  // Helper to download the PAC script (wpad + custom) and apply fallback rules.
+  //
+  // Note that the declaration is important here: |proxy_script_fetcher_| and
+  // |proxy_resolver_| must outlive |init_proxy_resolver_|.
+  scoped_ptr<InitProxyResolver> init_proxy_resolver_;
+
+  // Helper to poll the PAC script for changes.
+  scoped_ptr<ProxyScriptDeciderPoller> script_poller_;
+
+  State current_state_;
+
+  // Either OK or an ERR_* value indicating that a permanent error (e.g.
+  // failed to fetch the PAC script) prevents proxy resolution.
+  int permanent_error_;
+
+  // This is the log where any events generated by |init_proxy_resolver_| are
+  // sent to.
+  NetLog* net_log_;
+
+  // The earliest time at which we should run any proxy auto-config. (Used to
+  // stall re-configuration following an IP address change).
+  base::TimeTicks stall_proxy_autoconfig_until_;
+
+  // The amount of time to stall requests following IP address changes.
+  base::TimeDelta stall_proxy_auto_config_delay_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProxyService);
+};
+
+// Wrapper for invoking methods on a ProxyService synchronously.
+class NET_EXPORT SyncProxyServiceHelper
+    : public base::RefCountedThreadSafe<SyncProxyServiceHelper> {
+ public:
+  SyncProxyServiceHelper(MessageLoop* io_message_loop,
+                         ProxyService* proxy_service);
+
+  int ResolveProxy(const GURL& url,
+                   ProxyInfo* proxy_info,
+                   const BoundNetLog& net_log);
+  int ReconsiderProxyAfterError(const GURL& url,
+                                ProxyInfo* proxy_info,
+                                const BoundNetLog& net_log);
+
+ private:
+  friend class base::RefCountedThreadSafe<SyncProxyServiceHelper>;
+
+  virtual ~SyncProxyServiceHelper();
+
+  void StartAsyncResolve(const GURL& url, const BoundNetLog& net_log);
+  void StartAsyncReconsider(const GURL& url, const BoundNetLog& net_log);
+
+  void OnCompletion(int result);
+
+  MessageLoop* io_message_loop_;
+  ProxyService* proxy_service_;
+
+  base::WaitableEvent event_;
+  CompletionCallback callback_;
+  ProxyInfo proxy_info_;
+  int result_;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_SERVICE_H_
diff --git a/src/net/proxy/proxy_service_unittest.cc b/src/net/proxy/proxy_service_unittest.cc
new file mode 100644
index 0000000..341550e
--- /dev/null
+++ b/src/net/proxy/proxy_service_unittest.cc
@@ -0,0 +1,2699 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_service.h"
+
+#include <vector>
+
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/base/net_log_unittest.h"
+#include "net/base/test_completion_callback.h"
+#include "net/proxy/dhcp_proxy_script_fetcher.h"
+#include "net/proxy/mock_proxy_resolver.h"
+#include "net/proxy/mock_proxy_script_fetcher.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/proxy/proxy_resolver.h"
+#include "net/proxy/proxy_script_fetcher.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// TODO(eroman): Write a test which exercises
+//              ProxyService::SuspendAllPendingRequests().
+namespace net {
+namespace {
+
+// This polling policy will decide to poll every 1 ms.
+class ImmediatePollPolicy : public ProxyService::PacPollPolicy {
+ public:
+  ImmediatePollPolicy() {}
+
+  virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
+                            base::TimeDelta* next_delay) const OVERRIDE {
+    *next_delay = base::TimeDelta::FromMilliseconds(1);
+    return MODE_USE_TIMER;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy);
+};
+
+// This polling policy chooses a fantastically large delay. In other words, it
+// will never trigger a poll
+class NeverPollPolicy : public ProxyService::PacPollPolicy {
+ public:
+  NeverPollPolicy() {}
+
+  virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
+                            base::TimeDelta* next_delay) const OVERRIDE {
+    *next_delay = base::TimeDelta::FromDays(60);
+    return MODE_USE_TIMER;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy);
+};
+
+// This polling policy starts a poll immediately after network activity.
+class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy {
+ public:
+  ImmediateAfterActivityPollPolicy() {}
+
+  virtual Mode GetNextDelay(int error, base::TimeDelta current_delay,
+                            base::TimeDelta* next_delay) const OVERRIDE {
+    *next_delay = base::TimeDelta();
+    return MODE_START_AFTER_ACTIVITY;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy);
+};
+
+// This test fixture is used to partially disable the background polling done by
+// the ProxyService (which it uses to detect whenever its PAC script contents or
+// WPAD results have changed).
+//
+// We disable the feature by setting the poll interval to something really
+// large, so it will never actually be reached even on the slowest bots that run
+// these tests.
+//
+// We disable the polling in order to avoid any timing dependencies in the
+// tests. If the bot were to run the tests very slowly and we hadn't disabled
+// polling, then it might start a background re-try in the middle of our test
+// and confuse our expectations leading to flaky failures.
+//
+// The tests which verify the polling code re-enable the polling behavior but
+// are careful to avoid timing problems.
+class ProxyServiceTest : public testing::Test {
+ protected:
+  virtual void SetUp() OVERRIDE {
+    testing::Test::SetUp();
+    previous_policy_ =
+        ProxyService::set_pac_script_poll_policy(&never_poll_policy_);
+  }
+
+  virtual void TearDown() OVERRIDE {
+    // Restore the original policy.
+    ProxyService::set_pac_script_poll_policy(previous_policy_);
+    testing::Test::TearDown();
+  }
+
+ private:
+  NeverPollPolicy never_poll_policy_;
+  const ProxyService::PacPollPolicy* previous_policy_;
+};
+
+const char kValidPacScript1[] = "pac-script-v1-FindProxyForURL";
+const char kValidPacScript2[] = "pac-script-v2-FindProxyForURL";
+
+class MockProxyConfigService: public ProxyConfigService {
+ public:
+  explicit MockProxyConfigService(const ProxyConfig& config)
+      : availability_(CONFIG_VALID),
+        config_(config) {
+  }
+
+  explicit MockProxyConfigService(const std::string& pac_url)
+      : availability_(CONFIG_VALID),
+        config_(ProxyConfig::CreateFromCustomPacURL(GURL(pac_url))) {
+  }
+
+  virtual void AddObserver(Observer* observer) OVERRIDE {
+    observers_.AddObserver(observer);
+  }
+
+  virtual void RemoveObserver(Observer* observer) OVERRIDE {
+    observers_.RemoveObserver(observer);
+  }
+
+  virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* results)
+      OVERRIDE {
+    if (availability_ == CONFIG_VALID)
+      *results = config_;
+    return availability_;
+  }
+
+  void SetConfig(const ProxyConfig& config) {
+    availability_ = CONFIG_VALID;
+    config_ = config;
+    FOR_EACH_OBSERVER(Observer, observers_,
+                      OnProxyConfigChanged(config_, availability_));
+  }
+
+ private:
+  ConfigAvailability availability_;
+  ProxyConfig config_;
+  ObserverList<Observer, true> observers_;
+};
+
+}  // namespace
+
+TEST_F(ProxyServiceTest, Direct) {
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+  ProxyService service(new MockProxyConfigService(
+          ProxyConfig::CreateDirect()), resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  ProxyInfo info;
+  TestCompletionCallback callback;
+  CapturingBoundNetLog log;
+  int rv = service.ResolveProxy(
+      url, &info, callback.callback(), NULL, log.bound());
+  EXPECT_EQ(OK, rv);
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  EXPECT_TRUE(info.is_direct());
+
+  // Check the NetLog was filled correctly.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(3u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SERVICE));
+  EXPECT_TRUE(LogContainsEvent(
+      entries, 1, NetLog::TYPE_PROXY_SERVICE_RESOLVED_PROXY_LIST,
+      NetLog::PHASE_NONE));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SERVICE));
+}
+
+TEST_F(ProxyServiceTest, PAC) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  ProxyInfo info;
+  TestCompletionCallback callback;
+  CapturingBoundNetLog log;
+
+  int rv = service.ResolveProxy(
+      url, &info, callback.callback(), NULL, log.bound());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy:80", info.proxy_server().ToURI());
+  EXPECT_TRUE(info.did_use_pac_script());
+
+  // Check the NetLog was filled correctly.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_EQ(5u, entries.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 0, NetLog::TYPE_PROXY_SERVICE));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 2, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries, 4, NetLog::TYPE_PROXY_SERVICE));
+}
+
+// Test that the proxy resolver does not see the URL's username/password
+// or its reference section.
+TEST_F(ProxyServiceTest, PAC_NoIdentityOrHash) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://username:password@www.google.com/?ref#hash#hash");
+
+  ProxyInfo info;
+  TestCompletionCallback callback;
+  int rv = service.ResolveProxy(
+      url, &info, callback.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  // The URL should have been simplified, stripping the username/password/hash.
+  EXPECT_EQ(GURL("http://www.google.com/?ref"),
+                 resolver->pending_requests()[0]->url());
+
+  // We end here without ever completing the request -- destruction of
+  // ProxyService will cancel the outstanding request.
+}
+
+TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy:8080");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy:8080", info.proxy_server().ToURI());
+  EXPECT_TRUE(info.did_use_pac_script());
+
+  // Now, imagine that connecting to foopy:8080 fails: there is nothing
+  // left to fallback to, since our proxy list was NOT terminated by
+  // DIRECT.
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(
+      url, &info, callback2.callback(), NULL, BoundNetLog());
+  // ReconsiderProxyAfterError returns error indicating nothing left.
+  EXPECT_EQ(ERR_FAILED, rv);
+  EXPECT_TRUE(info.is_empty());
+}
+
+// Test that if the execution of the PAC script fails (i.e. javascript runtime
+// error), and the PAC settings are non-mandatory, that we fall-back to direct.
+TEST_F(ProxyServiceTest, PAC_RuntimeError) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://this-causes-js-error/");
+
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Simulate a failure in the PAC executor.
+  resolver->pending_requests()[0]->CompleteNow(ERR_PAC_SCRIPT_FAILED);
+
+  EXPECT_EQ(OK, callback1.WaitForResult());
+
+  // Since the PAC script was non-mandatory, we should have fallen-back to
+  // DIRECT.
+  EXPECT_TRUE(info.is_direct());
+  EXPECT_TRUE(info.did_use_pac_script());
+  EXPECT_EQ(1, info.config_id());
+}
+
+// The proxy list could potentially contain the DIRECT fallback choice
+// in a location other than the very end of the list, and could even
+// specify it multiple times.
+//
+// This is not a typical usage, but we will obey it.
+// (If we wanted to disallow this type of input, the right place to
+// enforce it would be in parsing the PAC result string).
+//
+// This test will use the PAC result string:
+//
+//   "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20"
+//
+// For which we expect it to try DIRECT, then foobar:10, then DIRECT again,
+// then foobar:20, and then give up and error.
+//
+// The important check of this test is to make sure that DIRECT is not somehow
+// cached as being a bad proxy.
+TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UsePacString(
+      "DIRECT ; PROXY foobar:10 ; DIRECT ; PROXY foobar:20");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_TRUE(info.is_direct());
+
+  // Fallback 1.
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foobar:10", info.proxy_server().ToURI());
+
+  // Fallback 2.
+  TestCompletionCallback callback3;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_TRUE(info.is_direct());
+
+  // Fallback 3.
+  TestCompletionCallback callback4;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foobar:20", info.proxy_server().ToURI());
+
+  // Fallback 4 -- Nothing to fall back to!
+  TestCompletionCallback callback5;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback5.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(ERR_FAILED, rv);
+  EXPECT_TRUE(info.is_empty());
+}
+
+TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) {
+  // Test whether the ProxyConfigSource set by the ProxyConfigService is applied
+  // to ProxyInfo after the proxy is resolved via a PAC script.
+  ProxyConfig config =
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
+  config.set_source(PROXY_CONFIG_SOURCE_TEST);
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+  ProxyService service(config_service, resolver, NULL);
+
+  // Resolve something.
+  GURL url("http://www.google.com/");
+  ProxyInfo info;
+  TestCompletionCallback callback;
+  int rv = service.ResolveProxy(
+      url, &info, callback.callback(), NULL, BoundNetLog());
+  ASSERT_EQ(ERR_IO_PENDING, rv);
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback.WaitForResult());
+  EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+  EXPECT_TRUE(info.did_use_pac_script());
+}
+
+TEST_F(ProxyServiceTest, ProxyResolverFails) {
+  // Test what happens when the ProxyResolver fails. The download and setting
+  // of the PAC script have already succeeded, so this corresponds with a
+  // javascript runtime error while calling FindProxyForURL().
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  // Start first resolve request.
+  GURL url("http://www.google.com/");
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Fail the first resolve request in MockAsyncProxyResolver.
+  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
+
+  // Although the proxy resolver failed the request, ProxyService implicitly
+  // falls-back to DIRECT.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_TRUE(info.is_direct());
+
+  // The second resolve request will try to run through the proxy resolver,
+  // regardless of whether the first request failed in it.
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      url, &info, callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // This time we will have the resolver succeed (perhaps the PAC script has
+  // a dependency on the current time).
+  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
+}
+
+TEST_F(ProxyServiceTest, ProxyScriptFetcherFailsDownloadingMandatoryPac) {
+  // Test what happens when the ProxyScriptResolver fails to download a
+  // mandatory PAC script.
+
+  ProxyConfig config(
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+  config.set_pac_mandatory(true);
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  // Start first resolve request.
+  GURL url("http://www.google.com/");
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(ERR_FAILED);
+
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // As the proxy resolver failed the request and is configured for a mandatory
+  // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+            callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+
+  // As the proxy resolver failed the request and is configured for a mandatory
+  // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      url, &info, callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, rv);
+  EXPECT_FALSE(info.is_direct());
+}
+
+TEST_F(ProxyServiceTest, ProxyResolverFailsParsingJavaScriptMandatoryPac) {
+  // Test what happens when the ProxyResolver fails that is configured to use a
+  // mandatory PAC script. The download of the PAC script has already
+  // succeeded but the PAC script contains no valid javascript.
+
+  ProxyConfig config(
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+  config.set_pac_mandatory(true);
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  DhcpProxyScriptFetcher* dhcp_fetcher = new DoNothingDhcpProxyScriptFetcher();
+  service.SetProxyScriptFetchers(fetcher, dhcp_fetcher);
+
+  // Start resolve request.
+  GURL url("http://www.google.com/");
+  ProxyInfo info;
+  TestCompletionCallback callback;
+  int rv = service.ResolveProxy(
+      url, &info, callback.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // Downloading the PAC script succeeds.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
+
+  EXPECT_FALSE(fetcher->has_pending_request());
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // Since ProxyScriptDecider failed to identify a valid PAC and PAC was
+  // mandatory for this configuration, the ProxyService must not implicitly
+  // fall-back to DIRECT.
+  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+            callback.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+}
+
+TEST_F(ProxyServiceTest, ProxyResolverFailsInJavaScriptMandatoryPac) {
+  // Test what happens when the ProxyResolver fails that is configured to use a
+  // mandatory PAC script. The download and setting of the PAC script have
+  // already succeeded, so this corresponds with a javascript runtime error
+  // while calling FindProxyForURL().
+
+  ProxyConfig config(
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+  config.set_pac_mandatory(true);
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  // Start first resolve request.
+  GURL url("http://www.google.com/");
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Fail the first resolve request in MockAsyncProxyResolver.
+  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
+
+  // As the proxy resolver failed the request and is configured for a mandatory
+  // PAC script, ProxyService must not implicitly fall-back to DIRECT.
+  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+            callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+
+  // The second resolve request will try to run through the proxy resolver,
+  // regardless of whether the first request failed in it.
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      url, &info, callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // This time we will have the resolver succeed (perhaps the PAC script has
+  // a dependency on the current time).
+  resolver->pending_requests()[0]->results()->UseNamedProxy("foopy_valid:8080");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy_valid:8080", info.proxy_server().ToURI());
+}
+
+TEST_F(ProxyServiceTest, ProxyFallback) {
+  // Test what happens when we specify multiple proxy servers and some of them
+  // are bad.
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  // Get the proxy information.
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first item is valid.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // Fake an error on the proxy.
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+
+  // The second proxy should be specified.
+  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+  // Report back that the second proxy worked.  This will globally mark the
+  // first proxy as bad.
+  service.ReportSuccess(info);
+
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(
+      url, &info, callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver -- the second result is already known
+  // to be bad, so we will not try to use it initially.
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy3:7070;foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback3.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
+
+  // We fake another error. It should now try the third one.
+  TestCompletionCallback callback4;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+
+  // We fake another error. At this point we have tried all of the
+  // proxy servers we thought were valid; next we try the proxy server
+  // that was in our bad proxies map (foopy1:8080).
+  TestCompletionCallback callback5;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback5.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // Fake another error, the last proxy is gone, the list should now be empty,
+  // so there is nothing left to try.
+  TestCompletionCallback callback6;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback6.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(ERR_FAILED, rv);
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_TRUE(info.is_empty());
+
+  // Look up proxies again
+  TestCompletionCallback callback7;
+  rv = service.ResolveProxy(url, &info, callback7.callback(), NULL,
+                            BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // This time, the first 3 results have been found to be bad, but only the
+  // first proxy has been confirmed ...
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy3:7070;foopy2:9090;foopy4:9091");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // ... therefore, we should see the second proxy first.
+  EXPECT_EQ(OK, callback7.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy3:7070", info.proxy_server().ToURI());
+
+  // TODO(nsylvain): Test that the proxy can be retried after the delay.
+}
+
+// This test is similar to ProxyFallback, but this time we have an explicit
+// fallback choice to DIRECT.
+TEST_F(ProxyServiceTest, ProxyFallbackToDirect) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  // Get the proxy information.
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UsePacString(
+      "PROXY foopy1:8080; PROXY foopy2:9090; DIRECT");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Get the first result.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // Fake an error on the proxy.
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+
+  // Now we get back the second proxy.
+  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+
+  // Fake an error on this proxy as well.
+  TestCompletionCallback callback3;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+
+  // Finally, we get back DIRECT.
+  EXPECT_TRUE(info.is_direct());
+
+  // Now we tell the proxy service that even DIRECT failed.
+  TestCompletionCallback callback4;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
+                                         BoundNetLog());
+  // There was nothing left to try after DIRECT, so we are out of
+  // choices.
+  EXPECT_EQ(ERR_FAILED, rv);
+}
+
+TEST_F(ProxyServiceTest, ProxyFallback_NewSettings) {
+  // Test proxy failover when new settings are available.
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  // Get the proxy information.
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // Set the result in proxy resolver.
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first item is valid.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // Fake an error on the proxy, and also a new configuration on the proxy.
+  config_service->SetConfig(
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy-new/proxy.pac")));
+
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy-new/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first proxy is still there since the configuration changed.
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // We fake another error. It should now ignore the first one.
+  TestCompletionCallback callback3;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback3.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+
+  // We simulate a new configuration.
+  config_service->SetConfig(
+      ProxyConfig::CreateFromCustomPacURL(
+          GURL("http://foopy-new2/proxy.pac")));
+
+  // We fake another error. It should go back to the first proxy.
+  TestCompletionCallback callback4;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback4.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy-new2/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback4.WaitForResult());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+}
+
+TEST_F(ProxyServiceTest, ProxyFallback_BadConfig) {
+  // Test proxy failover when the configuration is bad.
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  // Get the proxy information.
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first item is valid.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // Fake a proxy error.
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+
+  // The first proxy is ignored, and the second one is selected.
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+
+  // Fake a PAC failure.
+  ProxyInfo info2;
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(
+      url, &info2, callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // This simulates a javascript runtime error in the PAC script.
+  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
+
+  // Although the resolver failed, the ProxyService will implicitly fall-back
+  // to a DIRECT connection.
+  EXPECT_EQ(OK, callback3.WaitForResult());
+  EXPECT_TRUE(info2.is_direct());
+  EXPECT_FALSE(info2.is_empty());
+
+  // The PAC script will work properly next time and successfully return a
+  // proxy list. Since we have not marked the configuration as bad, it should
+  // "just work" the next time we call it.
+  ProxyInfo info3;
+  TestCompletionCallback callback4;
+  rv = service.ReconsiderProxyAfterError(url, &info3, callback4.callback(),
+                                         NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first proxy is not there since the it was added to the bad proxies
+  // list by the earlier ReconsiderProxyAfterError().
+  EXPECT_EQ(OK, callback4.WaitForResult());
+  EXPECT_FALSE(info3.is_direct());
+  EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
+}
+
+TEST_F(ProxyServiceTest, ProxyFallback_BadConfigMandatory) {
+  // Test proxy failover when the configuration is bad.
+
+  ProxyConfig config(
+      ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")));
+
+  config.set_pac_mandatory(true);
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  // Get the proxy information.
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      url, &info, callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first item is valid.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  // Fake a proxy error.
+  TestCompletionCallback callback2;
+  rv = service.ReconsiderProxyAfterError(url, &info, callback2.callback(), NULL,
+                                         BoundNetLog());
+  EXPECT_EQ(OK, rv);
+
+  // The first proxy is ignored, and the second one is selected.
+  EXPECT_FALSE(info.is_direct());
+  EXPECT_EQ("foopy2:9090", info.proxy_server().ToURI());
+
+  // Fake a PAC failure.
+  ProxyInfo info2;
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(
+      url, &info2, callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  // This simulates a javascript runtime error in the PAC script.
+  resolver->pending_requests()[0]->CompleteNow(ERR_FAILED);
+
+  // Although the resolver failed, the ProxyService will NOT fall-back
+  // to a DIRECT connection as it is configured as mandatory.
+  EXPECT_EQ(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED,
+            callback3.WaitForResult());
+  EXPECT_FALSE(info2.is_direct());
+  EXPECT_TRUE(info2.is_empty());
+
+  // The PAC script will work properly next time and successfully return a
+  // proxy list. Since we have not marked the configuration as bad, it should
+  // "just work" the next time we call it.
+  ProxyInfo info3;
+  TestCompletionCallback callback4;
+  rv = service.ReconsiderProxyAfterError(url, &info3, callback4.callback(),
+                                         NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(url, resolver->pending_requests()[0]->url());
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy(
+      "foopy1:8080;foopy2:9090");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // The first proxy is not there since the it was added to the bad proxies
+  // list by the earlier ReconsiderProxyAfterError().
+  EXPECT_EQ(OK, callback4.WaitForResult());
+  EXPECT_FALSE(info3.is_direct());
+  EXPECT_EQ("foopy1:8080", info3.proxy_server().ToURI());
+}
+
+TEST_F(ProxyServiceTest, ProxyBypassList) {
+  // Test that the proxy bypass rules are consulted.
+
+  TestCompletionCallback callback[2];
+  ProxyInfo info[2];
+  ProxyConfig config;
+  config.proxy_rules().ParseFromString("foopy1:8080;foopy2:9090");
+  config.set_auto_detect(false);
+  config.proxy_rules().bypass_rules.ParseFromString("*.org");
+
+  ProxyService service(
+      new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+
+  int rv;
+  GURL url1("http://www.webkit.org");
+  GURL url2("http://www.webkit.com");
+
+  // Request for a .org domain should bypass proxy.
+  rv = service.ResolveProxy(
+      url1, &info[0], callback[0].callback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_TRUE(info[0].is_direct());
+
+  // Request for a .com domain hits the proxy.
+  rv = service.ResolveProxy(
+      url2, &info[1], callback[1].callback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
+}
+
+
+TEST_F(ProxyServiceTest, PerProtocolProxyTests) {
+  ProxyConfig config;
+  config.proxy_rules().ParseFromString("http=foopy1:8080;https=foopy2:8080");
+  config.set_auto_detect(false);
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("http://www.msn.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+  }
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("ftp://ftp.google.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_TRUE(info.is_direct());
+    EXPECT_EQ("direct://", info.proxy_server().ToURI());
+  }
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("https://webbranch.techcu.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
+  }
+  {
+    config.proxy_rules().ParseFromString("foopy1:8080");
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("http://www.microsoft.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+  }
+}
+
+TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) {
+  // Test that the proxy config source is set correctly when resolving proxies
+  // using manual proxy rules. Namely, the config source should only be set if
+  // any of the rules were applied.
+  {
+    ProxyConfig config;
+    config.set_source(PROXY_CONFIG_SOURCE_TEST);
+    config.proxy_rules().ParseFromString("https=foopy2:8080");
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("http://www.google.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    ASSERT_EQ(OK, rv);
+    // Should be SOURCE_TEST, even if there are no HTTP proxies configured.
+    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+  }
+  {
+    ProxyConfig config;
+    config.set_source(PROXY_CONFIG_SOURCE_TEST);
+    config.proxy_rules().ParseFromString("https=foopy2:8080");
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("https://www.google.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    ASSERT_EQ(OK, rv);
+    // Used the HTTPS proxy. So source should be TEST.
+    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+  }
+  {
+    ProxyConfig config;
+    config.set_source(PROXY_CONFIG_SOURCE_TEST);
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("http://www.google.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    ASSERT_EQ(OK, rv);
+    // ProxyConfig is empty. Source should still be TEST.
+    EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source());
+  }
+}
+
+// If only HTTP and a SOCKS proxy are specified, check if ftp/https queries
+// fall back to the SOCKS proxy.
+TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) {
+  ProxyConfig config;
+  config.proxy_rules().ParseFromString("http=foopy1:8080;socks=foopy2:1080");
+  config.set_auto_detect(false);
+  EXPECT_EQ(ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME,
+            config.proxy_rules().type);
+
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("http://www.msn.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+  }
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("ftp://ftp.google.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
+  }
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("https://webbranch.techcu.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
+  }
+  {
+    ProxyService service(
+        new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL);
+    GURL test_url("unknown://www.microsoft.com");
+    ProxyInfo info;
+    TestCompletionCallback callback;
+    int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL,
+                                  BoundNetLog());
+    EXPECT_EQ(OK, rv);
+    EXPECT_FALSE(info.is_direct());
+    EXPECT_EQ("socks4://foopy2:1080", info.proxy_server().ToURI());
+  }
+}
+
+// Test cancellation of an in-progress request.
+TEST_F(ProxyServiceTest, CancelInProgressRequest) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  // Start 3 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Nothing has been sent to the proxy resolver yet, since the proxy
+  // resolver has not been configured yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // Successfully initialize the PAC script.
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  ProxyService::PacRequest* request2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), &request2, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  ASSERT_EQ(2u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
+
+  ProxyInfo info3;
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(GURL("http://request3"), &info3,
+                            callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+  ASSERT_EQ(3u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
+
+  // Cancel the second request
+  service.CancelPacRequest(request2);
+
+  ASSERT_EQ(2u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[1]->url());
+
+  // Complete the two un-cancelled requests.
+  // We complete the last one first, just to mix it up a bit.
+  resolver->pending_requests()[1]->results()->UseNamedProxy("request3:80");
+  resolver->pending_requests()[1]->CompleteNow(OK);
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Complete and verify that requests ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  EXPECT_FALSE(callback2.have_result());  // Cancelled.
+  ASSERT_EQ(1u, resolver->cancelled_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->cancelled_requests()[0]->url());
+
+  EXPECT_EQ(OK, callback3.WaitForResult());
+  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
+}
+
+// Test the initial PAC download for resolver that expects bytes.
+TEST_F(ProxyServiceTest, InitialPACScriptDownload) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 3 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyInfo info3;
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(GURL("http://request3"), &info3,
+                            callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, it will have been sent to the proxy
+  // resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(3u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
+  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[2]->url());
+
+  // Complete all the requests (in some order).
+  // Note that as we complete requests, they shift up in |pending_requests()|.
+
+  resolver->pending_requests()[2]->results()->UseNamedProxy("request3:80");
+  resolver->pending_requests()[2]->CompleteNow(OK);
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Complete and verify that requests ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+
+  EXPECT_EQ(OK, callback3.WaitForResult());
+  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
+}
+
+// Test changing the ProxyScriptFetcher while PAC download is in progress.
+TEST_F(ProxyServiceTest, ChangeScriptFetcherWhilePACDownloadInProgress) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 2 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+
+  // We now change out the ProxyService's script fetcher. We should restart
+  // the initialization with the new fetcher.
+
+  fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, it will have been sent to the proxy
+  // resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(2u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
+}
+
+// Test cancellation of a request, while the PAC script is being fetched.
+TEST_F(ProxyServiceTest, CancelWhilePACFetching) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 3 requests.
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  ProxyService::PacRequest* request1;
+  CapturingBoundNetLog log1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), &request1, log1.bound());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  ProxyService::PacRequest* request2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), &request2, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyInfo info3;
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(GURL("http://request3"), &info3,
+                            callback3.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // Cancel the first 2 requests.
+  service.CancelPacRequest(request1);
+  service.CancelPacRequest(request2);
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, it will have been sent to the
+  // proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request3"), resolver->pending_requests()[0]->url());
+
+  // Complete all the requests.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request3:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback3.WaitForResult());
+  EXPECT_EQ("request3:80", info3.proxy_server().ToURI());
+
+  EXPECT_TRUE(resolver->cancelled_requests().empty());
+
+  EXPECT_FALSE(callback1.have_result());  // Cancelled.
+  EXPECT_FALSE(callback2.have_result());  // Cancelled.
+
+  CapturingNetLog::CapturedEntryList entries1;
+  log1.GetEntries(&entries1);
+
+  // Check the NetLog for request 1 (which was cancelled) got filled properly.
+  EXPECT_EQ(4u, entries1.size());
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries1, 0, NetLog::TYPE_PROXY_SERVICE));
+  EXPECT_TRUE(LogContainsBeginEvent(
+      entries1, 1, NetLog::TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC));
+  // Note that TYPE_PROXY_SERVICE_WAITING_FOR_INIT_PAC is never completed before
+  // the cancellation occured.
+  EXPECT_TRUE(LogContainsEvent(
+      entries1, 2, NetLog::TYPE_CANCELLED, NetLog::PHASE_NONE));
+  EXPECT_TRUE(LogContainsEndEvent(
+      entries1, 3, NetLog::TYPE_PROXY_SERVICE));
+}
+
+// Test that if auto-detect fails, we fall-back to the custom pac.
+TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac) {
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://foopy/proxy.pac"));
+  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 2 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  ProxyService::PacRequest* request2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), &request2, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // It should be trying to auto-detect first -- FAIL the autodetect during
+  // the script download.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
+
+  // Next it should be trying the custom PAC url.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  // Now finally, the pending requests should have been sent to the resolver
+  // (which was initialized with custom PAC script).
+
+  ASSERT_EQ(2u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
+
+  // Complete the pending requests.
+  resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[1]->CompleteNow(OK);
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Verify that requests ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
+// This is the same test as FallbackFromAutodetectToCustomPac, except
+// the auto-detect script fails parsing rather than downloading.
+TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomPac2) {
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://foopy/proxy.pac"));
+  config.proxy_rules().ParseFromString("http=foopy:80");  // Won't be used.
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 2 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  ProxyService::PacRequest* request2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), &request2, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // It should be trying to auto-detect first -- succeed the download.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, "invalid-script-contents");
+
+  // The script contents passed failed basic verification step (since didn't
+  // contain token FindProxyForURL), so it was never passed to the resolver.
+
+  // Next it should be trying the custom PAC url.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  // Now finally, the pending requests should have been sent to the resolver
+  // (which was initialized with custom PAC script).
+
+  ASSERT_EQ(2u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[1]->url());
+
+  // Complete the pending requests.
+  resolver->pending_requests()[1]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[1]->CompleteNow(OK);
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Verify that requests ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
+// Test that if all of auto-detect, a custom PAC script, and manual settings
+// are given, then we will try them in that order.
+TEST_F(ProxyServiceTest, FallbackFromAutodetectToCustomToManual) {
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://foopy/proxy.pac"));
+  config.proxy_rules().ParseFromString("http=foopy:80");
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 2 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  ProxyService::PacRequest* request2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), &request2, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // It should be trying to auto-detect first -- fail the download.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
+
+  // Next it should be trying the custom PAC url -- fail the download.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
+
+  // Since we never managed to initialize a ProxyResolver, nothing should have
+  // been sent to it.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // Verify that requests ran as expected -- they should have fallen back to
+  // the manual proxy configuration for HTTP urls.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("foopy:80", info1.proxy_server().ToURI());
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("foopy:80", info2.proxy_server().ToURI());
+}
+
+// Test that the bypass rules are NOT applied when using autodetect.
+TEST_F(ProxyServiceTest, BypassDoesntApplyToPac) {
+  ProxyConfig config;
+  config.set_auto_detect(true);
+  config.set_pac_url(GURL("http://foopy/proxy.pac"));
+  config.proxy_rules().ParseFromString("http=foopy:80");  // Not used.
+  config.proxy_rules().bypass_rules.ParseFromString("www.google.com");
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 requests.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      GURL("http://www.google.com"), &info1, callback1.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // It should be trying to auto-detect first -- succeed the download.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://wpad/wpad.dat"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://www.google.com"),
+            resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Verify that request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // Start another request, it should pickup the bypass item.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(GURL("http://www.google.com"), &info2,
+                            callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://www.google.com"),
+            resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
+// Delete the ProxyService while InitProxyResolver has an outstanding
+// request to the script fetcher. When run under valgrind, should not
+// have any memory errors (used to be that the ProxyScriptFetcher was
+// being deleted prior to the InitProxyResolver).
+TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingFetch) {
+  ProxyConfig config =
+    ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac"));
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://www.google.com"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // InitProxyResolver should have issued a request to the ProxyScriptFetcher
+  // and be waiting on that to complete.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+}
+
+// Delete the ProxyService while InitProxyResolver has an outstanding
+// request to the proxy resolver. When run under valgrind, should not
+// have any memory errors (used to be that the ProxyResolver was
+// being deleted prior to the InitProxyResolver).
+TEST_F(ProxyServiceTest, DeleteWhileInitProxyResolverHasOutstandingSet) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  GURL url("http://www.google.com/");
+
+  ProxyInfo info;
+  TestCompletionCallback callback;
+  int rv = service.ResolveProxy(
+      url, &info, callback.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"),
+            resolver->pending_set_pac_script_request()->script_data()->url());
+}
+
+TEST_F(ProxyServiceTest, ResetProxyConfigService) {
+  ProxyConfig config1;
+  config1.proxy_rules().ParseFromString("foopy1:8080");
+  config1.set_auto_detect(false);
+  ProxyService service(
+      new MockProxyConfigService(config1),
+      new MockAsyncProxyResolverExpectsBytes, NULL);
+
+  ProxyInfo info;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_EQ("foopy1:8080", info.proxy_server().ToURI());
+
+  ProxyConfig config2;
+  config2.proxy_rules().ParseFromString("foopy2:8080");
+  config2.set_auto_detect(false);
+  service.ResetConfigService(new MockProxyConfigService(config2));
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info,
+                            callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
+}
+
+// Test that when going from a configuration that required PAC to one
+// that does NOT, we unset the variable |should_use_proxy_resolver_|.
+TEST_F(ProxyServiceTest, UpdateConfigFromPACToDirect) {
+  ProxyConfig config = ProxyConfig::CreateAutoDetect();
+
+  MockProxyConfigService* config_service = new MockProxyConfigService(config);
+  MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver;
+  ProxyService service(config_service, resolver, NULL);
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://www.google.com"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that nothing has been sent to the proxy resolver yet.
+  ASSERT_EQ(0u, resolver->pending_requests().size());
+
+  // Successfully set the autodetect script.
+  EXPECT_EQ(ProxyResolverScriptData::TYPE_AUTO_DETECT,
+            resolver->pending_set_pac_script_request()->script_data()->type());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  // Complete the pending request.
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Verify that request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // Force the ProxyService to pull down a new proxy configuration.
+  // (Even though the configuration isn't old/bad).
+  //
+  // This new configuration no longer has auto_detect set, so
+  // requests should complete synchronously now as direct-connect.
+  config_service->SetConfig(ProxyConfig::CreateDirect());
+
+  // Start another request -- the effective configuration has changed.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(GURL("http://www.google.com"), &info2,
+                            callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(OK, rv);
+
+  EXPECT_TRUE(info2.is_direct());
+}
+
+TEST_F(ProxyServiceTest, NetworkChangeTriggersPacRefetch) {
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  CapturingNetLog log;
+
+  ProxyService service(config_service, resolver, &log);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Disable the "wait after IP address changes" hack, so this unit-test can
+  // complete quickly.
+  service.set_stall_proxy_auto_config_delay(base::TimeDelta());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(GURL("http://request1"), &info1,
+                                callback1.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered initial download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, the request will have been sent to
+  // the proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // Now simluate a change in the network. The ProxyConfigService is still
+  // going to return the same PAC URL as before, but this URL needs to be
+  // refetched on the new network.
+  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
+  MessageLoop::current()->RunUntilIdle();  // Notification happens async.
+
+  // Start a second request.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(GURL("http://request2"), &info2,
+                            callback2.callback(), NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // This second request should have triggered the re-download of the PAC
+  // script (since we marked the network as having changed).
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // Simulate the PAC script fetch as having completed (this time with
+  // different data).
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
+
+  // Now that the PAC script is downloaded, the second request will have been
+  // sent to the proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending second request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+
+  // Check that the expected events were output to the log stream. In particular
+  // PROXY_CONFIG_CHANGED should have only been emitted once (for the initial
+  // setup), and NOT a second time when the IP address changed.
+  CapturingNetLog::CapturedEntryList entries;
+  log.GetEntries(&entries);
+
+  EXPECT_TRUE(LogContainsEntryWithType(entries, 0,
+                                       NetLog::TYPE_PROXY_CONFIG_CHANGED));
+  ASSERT_EQ(9u, entries.size());
+  for (size_t i = 1; i < entries.size(); ++i)
+    EXPECT_NE(NetLog::TYPE_PROXY_CONFIG_CHANGED, entries[i].type);
+}
+
+// This test verifies that the PAC script specified by the settings is
+// periodically polled for changes. Specifically, if the initial fetch fails due
+// to a network error, we will eventually re-configure the service to use the
+// script once it becomes available.
+TEST_F(ProxyServiceTest, PACScriptRefetchAfterFailure) {
+  // Change the retry policy to wait a mere 1 ms before retrying, so the test
+  // runs quickly.
+  ImmediatePollPolicy poll_policy;
+  ProxyService::set_pac_script_poll_policy(&poll_policy);
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      GURL("http://request1"), &info1, callback1.callback(),
+      NULL, BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered initial download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  //
+  // We simulate a failed download attempt, the proxy service should now
+  // fall-back to DIRECT connections.
+  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
+
+  ASSERT_TRUE(resolver->pending_requests().empty());
+
+  // Wait for completion callback, and verify it used DIRECT.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_TRUE(info1.is_direct());
+
+  // At this point we have initialized the proxy service using a PAC script,
+  // however it failed and fell-back to DIRECT.
+  //
+  // A background task to periodically re-check the PAC script for validity will
+  // have been started. We will now wait for the next download attempt to start.
+  //
+  // Note that we shouldn't have to wait long here, since our test enables a
+  // special unit-test mode.
+  fetcher->WaitUntilFetch();
+
+  ASSERT_TRUE(resolver->pending_requests().empty());
+
+  // Make sure that our background checker is trying to download the expected
+  // PAC script (same one as before). This time we will simulate a successful
+  // download of the script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  MessageLoop::current()->RunUntilIdle();
+
+  // Now that the PAC script is downloaded, it should be used to initialize the
+  // ProxyResolver. Simulate a successful parse.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  // At this point the ProxyService should have re-configured itself to use the
+  // PAC script (thereby recovering from the initial fetch failure). We will
+  // verify that the next Resolve request uses the resolver rather than
+  // DIRECT.
+
+  // Start a second request.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      GURL("http://request2"), &info2, callback2.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that it was sent to the resolver.
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending second request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
+// This test verifies that the PAC script specified by the settings is
+// periodically polled for changes. Specifically, if the initial fetch succeeds,
+// however at a later time its *contents* change, we will eventually
+// re-configure the service to use the new script.
+TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentChange) {
+  // Change the retry policy to wait a mere 1 ms before retrying, so the test
+  // runs quickly.
+  ImmediatePollPolicy poll_policy;
+  ProxyService::set_pac_script_poll_policy(&poll_policy);
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      GURL("http://request1"), &info1, callback1.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered initial download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, the request will have been sent to
+  // the proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // At this point we have initialized the proxy service using a PAC script.
+  //
+  // A background task to periodically re-check the PAC script for validity will
+  // have been started. We will now wait for the next download attempt to start.
+  //
+  // Note that we shouldn't have to wait long here, since our test enables a
+  // special unit-test mode.
+  fetcher->WaitUntilFetch();
+
+  ASSERT_TRUE(resolver->pending_requests().empty());
+
+  // Make sure that our background checker is trying to download the expected
+  // PAC script (same one as before). This time we will simulate a successful
+  // download of a DIFFERENT script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript2);
+
+  MessageLoop::current()->RunUntilIdle();
+
+  // Now that the PAC script is downloaded, it should be used to initialize the
+  // ProxyResolver. Simulate a successful parse.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript2),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  // At this point the ProxyService should have re-configured itself to use the
+  // new PAC script.
+
+  // Start a second request.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      GURL("http://request2"), &info2, callback2.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that it was sent to the resolver.
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending second request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
+// This test verifies that the PAC script specified by the settings is
+// periodically polled for changes. Specifically, if the initial fetch succeeds
+// and so does the next poll, however the contents of the downloaded script
+// have NOT changed, then we do not bother to re-initialize the proxy resolver.
+TEST_F(ProxyServiceTest, PACScriptRefetchAfterContentUnchanged) {
+  // Change the retry policy to wait a mere 1 ms before retrying, so the test
+  // runs quickly.
+  ImmediatePollPolicy poll_policy;
+  ProxyService::set_pac_script_poll_policy(&poll_policy);
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      GURL("http://request1"), &info1, callback1.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered initial download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, the request will have been sent to
+  // the proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // At this point we have initialized the proxy service using a PAC script.
+  //
+  // A background task to periodically re-check the PAC script for validity will
+  // have been started. We will now wait for the next download attempt to start.
+  //
+  // Note that we shouldn't have to wait long here, since our test enables a
+  // special unit-test mode.
+  fetcher->WaitUntilFetch();
+
+  ASSERT_TRUE(resolver->pending_requests().empty());
+
+  // Make sure that our background checker is trying to download the expected
+  // PAC script (same one as before). We will simulate the same response as
+  // last time (i.e. the script is unchanged).
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  MessageLoop::current()->RunUntilIdle();
+
+  ASSERT_FALSE(resolver->has_pending_set_pac_script_request());
+
+  // At this point the ProxyService is still running the same PAC script as
+  // before.
+
+  // Start a second request.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      GURL("http://request2"), &info2, callback2.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // Check that it was sent to the resolver.
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending second request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+}
+
+// This test verifies that the PAC script specified by the settings is
+// periodically polled for changes. Specifically, if the initial fetch succeeds,
+// however at a later time it starts to fail, we should re-configure the
+// ProxyService to stop using that PAC script.
+TEST_F(ProxyServiceTest, PACScriptRefetchAfterSuccess) {
+  // Change the retry policy to wait a mere 1 ms before retrying, so the test
+  // runs quickly.
+  ImmediatePollPolicy poll_policy;
+  ProxyService::set_pac_script_poll_policy(&poll_policy);
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      GURL("http://request1"), &info1, callback1.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered initial download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, the request will have been sent to
+  // the proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // At this point we have initialized the proxy service using a PAC script.
+  //
+  // A background task to periodically re-check the PAC script for validity will
+  // have been started. We will now wait for the next download attempt to start.
+  //
+  // Note that we shouldn't have to wait long here, since our test enables a
+  // special unit-test mode.
+  fetcher->WaitUntilFetch();
+
+  ASSERT_TRUE(resolver->pending_requests().empty());
+
+  // Make sure that our background checker is trying to download the expected
+  // PAC script (same one as before). This time we will simulate a failure
+  // to download the script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
+
+  MessageLoop::current()->RunUntilIdle();
+
+  // At this point the ProxyService should have re-configured itself to use
+  // DIRECT connections rather than the given proxy resolver.
+
+  // Start a second request.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      GURL("http://request2"), &info2, callback2.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_TRUE(info2.is_direct());
+}
+
+// Tests that the code which decides at what times to poll the PAC
+// script follows the expected policy.
+TEST_F(ProxyServiceTest, PACScriptPollingPolicy) {
+  // Retrieve the internal polling policy implementation used by ProxyService.
+  scoped_ptr<ProxyService::PacPollPolicy> policy =
+      ProxyService::CreateDefaultPacPollPolicy();
+
+  int error;
+  ProxyService::PacPollPolicy::Mode mode;
+  const base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(-1);
+  base::TimeDelta delay = initial_delay;
+
+  // --------------------------------------------------
+  // Test the poll sequence in response to a failure.
+  // --------------------------------------------------
+  error = ERR_NAME_NOT_RESOLVED;
+
+  // Poll #0
+  mode = policy->GetNextDelay(error, initial_delay, &delay);
+  EXPECT_EQ(8, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode);
+
+  // Poll #1
+  mode = policy->GetNextDelay(error, delay, &delay);
+  EXPECT_EQ(32, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+
+  // Poll #2
+  mode = policy->GetNextDelay(error, delay, &delay);
+  EXPECT_EQ(120, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+
+  // Poll #3
+  mode = policy->GetNextDelay(error, delay, &delay);
+  EXPECT_EQ(14400, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+
+  // Poll #4
+  mode = policy->GetNextDelay(error, delay, &delay);
+  EXPECT_EQ(14400, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+
+  // --------------------------------------------------
+  // Test the poll sequence in response to a success.
+  // --------------------------------------------------
+  error = OK;
+
+  // Poll #0
+  mode = policy->GetNextDelay(error, initial_delay, &delay);
+  EXPECT_EQ(43200, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+
+  // Poll #1
+  mode = policy->GetNextDelay(error, delay, &delay);
+  EXPECT_EQ(43200, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+
+  // Poll #2
+  mode = policy->GetNextDelay(error, delay, &delay);
+  EXPECT_EQ(43200, delay.InSeconds());
+  EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode);
+}
+
+// This tests the polling of the PAC script. Specifically, it tests that
+// polling occurs in response to user activity.
+TEST_F(ProxyServiceTest, PACScriptRefetchAfterActivity) {
+  ImmediateAfterActivityPollPolicy poll_policy;
+  ProxyService::set_pac_script_poll_policy(&poll_policy);
+
+  MockProxyConfigService* config_service =
+      new MockProxyConfigService("http://foopy/proxy.pac");
+
+  MockAsyncProxyResolverExpectsBytes* resolver =
+      new MockAsyncProxyResolverExpectsBytes;
+
+  ProxyService service(config_service, resolver, NULL);
+
+  MockProxyScriptFetcher* fetcher = new MockProxyScriptFetcher;
+  service.SetProxyScriptFetchers(fetcher,
+                                 new DoNothingDhcpProxyScriptFetcher());
+
+  // Start 1 request.
+
+  ProxyInfo info1;
+  TestCompletionCallback callback1;
+  int rv = service.ResolveProxy(
+      GURL("http://request1"), &info1, callback1.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // The first request should have triggered initial download of PAC script.
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // Nothing has been sent to the resolver yet.
+  EXPECT_TRUE(resolver->pending_requests().empty());
+
+  // At this point the ProxyService should be waiting for the
+  // ProxyScriptFetcher to invoke its completion callback, notifying it of
+  // PAC script download completion.
+  fetcher->NotifyFetchCompletion(OK, kValidPacScript1);
+
+  // Now that the PAC script is downloaded, the request will have been sent to
+  // the proxy resolver.
+  EXPECT_EQ(ASCIIToUTF16(kValidPacScript1),
+            resolver->pending_set_pac_script_request()->script_data()->utf16());
+  resolver->pending_set_pac_script_request()->CompleteNow(OK);
+
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request1"), resolver->pending_requests()[0]->url());
+
+  // Complete the pending request.
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request1:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  // Wait for completion callback, and verify that the request ran as expected.
+  EXPECT_EQ(OK, callback1.WaitForResult());
+  EXPECT_EQ("request1:80", info1.proxy_server().ToURI());
+
+  // At this point we have initialized the proxy service using a PAC script.
+  // Our PAC poller is set to update ONLY in response to network activity,
+  // (i.e. another call to ResolveProxy()).
+
+  ASSERT_FALSE(fetcher->has_pending_request());
+  ASSERT_TRUE(resolver->pending_requests().empty());
+
+  // Start a second request.
+  ProxyInfo info2;
+  TestCompletionCallback callback2;
+  rv = service.ResolveProxy(
+      GURL("http://request2"), &info2, callback2.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(ERR_IO_PENDING, rv);
+
+  // This request should have sent work to the resolver; complete it.
+  ASSERT_EQ(1u, resolver->pending_requests().size());
+  EXPECT_EQ(GURL("http://request2"), resolver->pending_requests()[0]->url());
+  resolver->pending_requests()[0]->results()->UseNamedProxy("request2:80");
+  resolver->pending_requests()[0]->CompleteNow(OK);
+
+  EXPECT_EQ(OK, callback2.WaitForResult());
+  EXPECT_EQ("request2:80", info2.proxy_server().ToURI());
+
+  // In response to getting that resolve request, the poller should have
+  // started the next poll, and made it as far as to request the download.
+
+  EXPECT_TRUE(fetcher->has_pending_request());
+  EXPECT_EQ(GURL("http://foopy/proxy.pac"), fetcher->pending_request_url());
+
+  // This time we will fail the download, to simulate a PAC script change.
+  fetcher->NotifyFetchCompletion(ERR_FAILED, "");
+
+  // Drain the message loop, so ProxyService is notified of the change
+  // and has a chance to re-configure itself.
+  MessageLoop::current()->RunUntilIdle();
+
+  // Start a third request -- this time we expect to get a direct connection
+  // since the PAC script poller experienced a failure.
+  ProxyInfo info3;
+  TestCompletionCallback callback3;
+  rv = service.ResolveProxy(
+      GURL("http://request3"), &info3, callback3.callback(), NULL,
+      BoundNetLog());
+  EXPECT_EQ(OK, rv);
+  EXPECT_TRUE(info3.is_direct());
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_service_v8.cc b/src/net/proxy/proxy_service_v8.cc
new file mode 100644
index 0000000..44ae82c
--- /dev/null
+++ b/src/net/proxy/proxy_service_v8.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/proxy_service_v8.h"
+
+#include "base/logging.h"
+#include "net/proxy/multi_threaded_proxy_resolver.h"
+#include "net/proxy/network_delegate_error_observer.h"
+#include "net/proxy/proxy_resolver.h"
+#include "net/proxy/proxy_resolver_js_bindings.h"
+#include "net/proxy/proxy_resolver_v8.h"
+#include "net/proxy/proxy_service.h"
+#include "net/proxy/sync_host_resolver_bridge.h"
+
+namespace net {
+namespace {
+
+// This factory creates V8ProxyResolvers with appropriate javascript bindings.
+class ProxyResolverFactoryForV8 : public ProxyResolverFactory {
+ public:
+  // |async_host_resolver|, |io_loop| and |net_log| must remain
+  // valid for the duration of our lifetime.
+  // |async_host_resolver| will only be operated on |io_loop|.
+  // TODO(willchan): remove io_loop and replace it with origin_loop.
+  ProxyResolverFactoryForV8(HostResolver* async_host_resolver,
+                            MessageLoop* io_loop,
+                            base::MessageLoopProxy* origin_loop,
+                            NetLog* net_log,
+                            NetworkDelegate* network_delegate)
+      : ProxyResolverFactory(true /*expects_pac_bytes*/),
+        async_host_resolver_(async_host_resolver),
+        io_loop_(io_loop),
+        origin_loop_(origin_loop),
+        net_log_(net_log),
+        network_delegate_(network_delegate) {
+  }
+
+  virtual ProxyResolver* CreateProxyResolver() OVERRIDE {
+    // Create a synchronous host resolver wrapper that operates
+    // |async_host_resolver_| on |io_loop_|.
+    SyncHostResolverBridge* sync_host_resolver =
+        new SyncHostResolverBridge(async_host_resolver_, io_loop_);
+
+    NetworkDelegateErrorObserver* error_observer =
+        new NetworkDelegateErrorObserver(
+            network_delegate_, origin_loop_.get());
+
+    // ProxyResolverJSBindings takes ownership of |error_observer| and
+    // |sync_host_resolver|.
+    ProxyResolverJSBindings* js_bindings =
+        ProxyResolverJSBindings::CreateDefault(
+            sync_host_resolver, net_log_, error_observer);
+
+    // ProxyResolverV8 takes ownership of |js_bindings|.
+    return new ProxyResolverV8(js_bindings);
+  }
+
+ private:
+  HostResolver* const async_host_resolver_;
+  MessageLoop* io_loop_;
+  scoped_refptr<base::MessageLoopProxy> origin_loop_;
+  NetLog* net_log_;
+  NetworkDelegate* network_delegate_;
+};
+
+}  // namespace
+
+// static
+ProxyService* CreateProxyServiceUsingV8ProxyResolver(
+    ProxyConfigService* proxy_config_service,
+    size_t num_pac_threads,
+    ProxyScriptFetcher* proxy_script_fetcher,
+    DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+    HostResolver* host_resolver,
+    NetLog* net_log,
+    NetworkDelegate* network_delegate) {
+  DCHECK(proxy_config_service);
+  DCHECK(proxy_script_fetcher);
+  DCHECK(dhcp_proxy_script_fetcher);
+  DCHECK(host_resolver);
+
+  if (num_pac_threads == 0)
+    num_pac_threads = ProxyService::kDefaultNumPacThreads;
+
+  ProxyResolverFactory* sync_resolver_factory =
+      new ProxyResolverFactoryForV8(
+          host_resolver,
+          MessageLoop::current(),
+          base::MessageLoopProxy::current(),
+          net_log,
+          network_delegate);
+
+  ProxyResolver* proxy_resolver =
+      new MultiThreadedProxyResolver(sync_resolver_factory, num_pac_threads);
+
+  ProxyService* proxy_service =
+      new ProxyService(proxy_config_service, proxy_resolver, net_log);
+
+  // Configure fetchers to use for PAC script downloads and auto-detect.
+  proxy_service->SetProxyScriptFetchers(proxy_script_fetcher,
+                                        dhcp_proxy_script_fetcher);
+
+  return proxy_service;
+}
+
+}  // namespace net
diff --git a/src/net/proxy/proxy_service_v8.h b/src/net/proxy/proxy_service_v8.h
new file mode 100644
index 0000000..0ff574d
--- /dev/null
+++ b/src/net/proxy/proxy_service_v8.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_PROXY_SERVICE_V8_H_
+#define NET_PROXY_PROXY_SERVICE_V8_H_
+
+#include "base/basictypes.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class DhcpProxyScriptFetcher;
+class HostResolver;
+class NetLog;
+class NetworkDelegate;
+class ProxyConfigService;
+class ProxyScriptFetcher;
+class ProxyService;
+
+// Creates a proxy service that polls |proxy_config_service| to notice when
+// the proxy settings change. We take ownership of |proxy_config_service|.
+//
+// |num_pac_threads| specifies the maximum number of threads to use for
+// executing PAC scripts. Threads are created lazily on demand.
+// If |0| is specified, then a default number of threads will be selected.
+//
+// Having more threads avoids stalling proxy resolve requests when the
+// PAC script takes a while to run. This is particularly a problem when PAC
+// scripts do synchronous DNS resolutions, since that can take on the order
+// of seconds.
+//
+// However, the disadvantages of using more than 1 thread are:
+//   (a) can cause compatibility issues for scripts that rely on side effects
+//       between runs (such scripts should not be common though).
+//   (b) increases the memory used by proxy resolving, as each thread will
+//       duplicate its own script context.
+
+// |proxy_script_fetcher| specifies the dependency to use for downloading
+// any PAC scripts. The resulting ProxyService will take ownership of it.
+//
+// |dhcp_proxy_script_fetcher| specifies the dependency to use for attempting
+// to retrieve the most appropriate PAC script configured in DHCP. The
+// resulting ProxyService will take ownership of it.
+//
+// |host_resolver| points to the host resolving dependency the PAC script
+// should use for any DNS queries. It must remain valid throughout the
+// lifetime of the ProxyService.
+//
+// ##########################################################################
+// # See the warnings in net/proxy/proxy_resolver_v8.h describing the
+// # multi-threading model. In order for this to be safe to use, *ALL* the
+// # other V8's running in the process must use v8::Locker.
+// ##########################################################################
+NET_EXPORT ProxyService* CreateProxyServiceUsingV8ProxyResolver(
+    ProxyConfigService* proxy_config_service,
+    size_t num_pac_threads,
+    ProxyScriptFetcher* proxy_script_fetcher,
+    DhcpProxyScriptFetcher* dhcp_proxy_script_fetcher,
+    HostResolver* host_resolver,
+    NetLog* net_log,
+    NetworkDelegate* network_delegate);
+
+}  // namespace net
+
+#endif  // NET_PROXY_PROXY_SERVICE_V8_H_
diff --git a/src/net/proxy/sync_host_resolver.h b/src/net/proxy/sync_host_resolver.h
new file mode 100644
index 0000000..153dfad
--- /dev/null
+++ b/src/net/proxy/sync_host_resolver.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_PROXY_SYNC_HOST_RESOLVER_H_
+#define NET_PROXY_SYNC_HOST_RESOLVER_H_
+
+#include "net/base/host_resolver.h"
+#include "net/base/net_export.h"
+
+namespace net {
+
+class BoundNetLog;
+
+// Interface used by ProxyResolverJSBindings to abstract a synchronous host
+// resolver module (which includes a Shutdown method).
+class NET_EXPORT_PRIVATE SyncHostResolver {
+ public:
+  virtual ~SyncHostResolver() {}
+
+  virtual int Resolve(const HostResolver::RequestInfo& info,
+                      AddressList* addresses,
+                      const BoundNetLog& net_log) = 0;
+
+  // Optionally aborts any blocking resolves that are in progress.
+  virtual void Shutdown() = 0;
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_SYNC_HOST_RESOLVER_H_
diff --git a/src/net/proxy/sync_host_resolver_bridge.cc b/src/net/proxy/sync_host_resolver_bridge.cc
new file mode 100644
index 0000000..9f55524
--- /dev/null
+++ b/src/net/proxy/sync_host_resolver_bridge.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/sync_host_resolver_bridge.h"
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+
+namespace net {
+
+// SyncHostResolverBridge::Core ----------------------------------------------
+
+class SyncHostResolverBridge::Core
+    : public base::RefCountedThreadSafe<SyncHostResolverBridge::Core> {
+ public:
+  Core(HostResolver* resolver, MessageLoop* host_resolver_loop);
+
+  int ResolveSynchronously(const HostResolver::RequestInfo& info,
+                           AddressList* addresses,
+                           const BoundNetLog& net_log);
+
+  // Returns true if Shutdown() has been called.
+  bool HasShutdown() const {
+    base::AutoLock l(lock_);
+    return HasShutdownLocked();
+  }
+
+  // Called on |host_resolver_loop_|.
+  void Shutdown();
+
+ private:
+  friend class base::RefCountedThreadSafe<SyncHostResolverBridge::Core>;
+  ~Core() {}
+
+  bool HasShutdownLocked() const {
+    return has_shutdown_;
+  }
+
+  // Called on |host_resolver_loop_|.
+  void StartResolve(const HostResolver::RequestInfo& info,
+                    AddressList* addresses,
+                    const BoundNetLog& net_log);
+
+  // Called on |host_resolver_loop_|.
+  void OnResolveCompletion(int result);
+
+  // Not called on |host_resolver_loop_|.
+  int WaitForResolveCompletion();
+
+  HostResolver* const host_resolver_;
+  MessageLoop* const host_resolver_loop_;
+  // The result from the current request (set on |host_resolver_loop_|).
+  int err_;
+  // The currently outstanding request to |host_resolver_|, or NULL.
+  HostResolver::RequestHandle outstanding_request_;
+
+  // Event to notify completion of resolve request.  We always Signal() on
+  // |host_resolver_loop_| and Wait() on a different thread.
+  base::WaitableEvent event_;
+
+  // True if Shutdown() has been called. Must hold |lock_| to access it.
+  bool has_shutdown_;
+
+  // Mutex to guard accesses to |has_shutdown_|.
+      mutable base::Lock lock_;
+
+  DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
+SyncHostResolverBridge::Core::Core(HostResolver* host_resolver,
+                                   MessageLoop* host_resolver_loop)
+    : host_resolver_(host_resolver),
+      host_resolver_loop_(host_resolver_loop),
+      err_(0),
+      outstanding_request_(NULL),
+      event_(true, false),
+      has_shutdown_(false) {}
+
+int SyncHostResolverBridge::Core::ResolveSynchronously(
+    const HostResolver::RequestInfo& info,
+    net::AddressList* addresses,
+    const BoundNetLog& net_log) {
+  // Otherwise start an async resolve on the resolver's thread.
+  host_resolver_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&Core::StartResolve, this, info, addresses, net_log));
+
+  return WaitForResolveCompletion();
+}
+
+void SyncHostResolverBridge::Core::StartResolve(
+    const HostResolver::RequestInfo& info,
+    net::AddressList* addresses,
+    const BoundNetLog& net_log) {
+  DCHECK_EQ(MessageLoop::current(), host_resolver_loop_);
+  DCHECK(!outstanding_request_);
+
+  if (HasShutdown())
+    return;
+
+  int error = host_resolver_->Resolve(
+      info, addresses, base::Bind(&Core::OnResolveCompletion, this),
+      &outstanding_request_, net_log);
+  if (error != ERR_IO_PENDING)
+    OnResolveCompletion(error);  // Completed synchronously.
+}
+
+void SyncHostResolverBridge::Core::OnResolveCompletion(int result) {
+  DCHECK_EQ(MessageLoop::current(), host_resolver_loop_);
+  err_ = result;
+  outstanding_request_ = NULL;
+  event_.Signal();
+}
+
+int SyncHostResolverBridge::Core::WaitForResolveCompletion() {
+  DCHECK_NE(MessageLoop::current(), host_resolver_loop_);
+  event_.Wait();
+
+  {
+    base::AutoLock l(lock_);
+    if (HasShutdownLocked())
+      return ERR_ABORTED;
+    event_.Reset();
+  }
+
+  return err_;
+}
+
+void SyncHostResolverBridge::Core::Shutdown() {
+  DCHECK_EQ(MessageLoop::current(), host_resolver_loop_);
+
+  if (outstanding_request_) {
+    host_resolver_->CancelRequest(outstanding_request_);
+    outstanding_request_ = NULL;
+  }
+
+  {
+    base::AutoLock l(lock_);
+    has_shutdown_ = true;
+  }
+
+  // Wake up the PAC thread in case it was waiting for resolve completion.
+  event_.Signal();
+}
+
+// SyncHostResolverBridge -----------------------------------------------------
+
+SyncHostResolverBridge::SyncHostResolverBridge(HostResolver* host_resolver,
+                                               MessageLoop* host_resolver_loop)
+    : host_resolver_loop_(host_resolver_loop),
+      core_(new Core(host_resolver, host_resolver_loop)) {
+  DCHECK(host_resolver_loop_);
+}
+
+SyncHostResolverBridge::~SyncHostResolverBridge() {
+  DCHECK(core_->HasShutdown());
+}
+
+int SyncHostResolverBridge::Resolve(const HostResolver::RequestInfo& info,
+                                    AddressList* addresses,
+                                    const BoundNetLog& net_log) {
+  return core_->ResolveSynchronously(info, addresses, net_log);
+}
+
+void SyncHostResolverBridge::Shutdown() {
+  DCHECK_EQ(MessageLoop::current(), host_resolver_loop_);
+  core_->Shutdown();
+}
+
+}  // namespace net
diff --git a/src/net/proxy/sync_host_resolver_bridge.h b/src/net/proxy/sync_host_resolver_bridge.h
new file mode 100644
index 0000000..1de67b5
--- /dev/null
+++ b/src/net/proxy/sync_host_resolver_bridge.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2012 The Chromium Authors. 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_PROXY_SYNC_HOST_RESOLVER_BRIDGE_H_
+#define NET_PROXY_SYNC_HOST_RESOLVER_BRIDGE_H_
+
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "net/proxy/sync_host_resolver.h"
+
+class MessageLoop;
+
+namespace net {
+
+// Wrapper around HostResolver to give a sync API while running the resolver
+// in async mode on |host_resolver_loop|.
+class NET_EXPORT_PRIVATE SyncHostResolverBridge : public SyncHostResolver {
+ public:
+  SyncHostResolverBridge(HostResolver* host_resolver,
+                         MessageLoop* host_resolver_loop);
+
+  virtual ~SyncHostResolverBridge();
+
+  // SyncHostResolver methods:
+  virtual int Resolve(const HostResolver::RequestInfo& info,
+                      AddressList* addresses,
+                      const BoundNetLog& net_log) OVERRIDE;
+
+  // The Shutdown() method should be called prior to destruction, from
+  // |host_resolver_loop_|. It aborts any in progress synchronous resolves, to
+  // prevent deadlocks from happening.
+  virtual void Shutdown() OVERRIDE;
+
+ private:
+  class Core;
+
+  MessageLoop* const host_resolver_loop_;
+  scoped_refptr<Core> core_;
+  DISALLOW_COPY_AND_ASSIGN(SyncHostResolverBridge);
+};
+
+}  // namespace net
+
+#endif  // NET_PROXY_SYNC_HOST_RESOLVER_BRIDGE_H_
diff --git a/src/net/proxy/sync_host_resolver_bridge_unittest.cc b/src/net/proxy/sync_host_resolver_bridge_unittest.cc
new file mode 100644
index 0000000..81ec33e
--- /dev/null
+++ b/src/net/proxy/sync_host_resolver_bridge_unittest.cc
@@ -0,0 +1,244 @@
+// Copyright (c) 2012 The Chromium Authors. 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/proxy/sync_host_resolver_bridge.h"
+
+#include "base/threading/thread.h"
+#include "base/synchronization/waitable_event.h"
+#include "net/base/address_list.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_log.h"
+#include "net/proxy/multi_threaded_proxy_resolver.h"
+#include "net/base/test_completion_callback.h"
+#include "net/proxy/proxy_info.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// TODO(eroman): This test should be moved into
+//               multi_threaded_proxy_resolver_unittest.cc.
+
+namespace net {
+
+namespace {
+
+// This implementation of HostResolver allows blocking until a resolve request
+// has been received. The resolve requests it receives will never be completed.
+class BlockableHostResolver : public HostResolver {
+ public:
+  BlockableHostResolver()
+      : event_(true, false),
+        was_request_cancelled_(false) {
+  }
+
+  virtual int Resolve(const RequestInfo& info,
+                      AddressList* addresses,
+                      const CompletionCallback& callback,
+                      RequestHandle* out_req,
+                      const BoundNetLog& net_log) OVERRIDE {
+    EXPECT_FALSE(callback.is_null());
+    EXPECT_TRUE(out_req);
+    *out_req = reinterpret_cast<RequestHandle*>(1);  // Magic value.
+
+    // Indicate to the caller that a request was received.
+    event_.Signal();
+
+    // We return ERR_IO_PENDING, as this request will NEVER be completed.
+    // Expectation is for the caller to later cancel the request.
+    return ERR_IO_PENDING;
+  }
+
+  virtual int ResolveFromCache(const RequestInfo& info,
+                               AddressList* addresses,
+                               const BoundNetLog& net_log) OVERRIDE {
+    NOTIMPLEMENTED();
+    return ERR_UNEXPECTED;
+  }
+
+  virtual void CancelRequest(RequestHandle req) OVERRIDE {
+    EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req);
+    was_request_cancelled_ = true;
+  }
+
+  // Waits until Resolve() has been called.
+  void WaitUntilRequestIsReceived() {
+    event_.Wait();
+  }
+
+  bool was_request_cancelled() const {
+    return was_request_cancelled_;
+  }
+
+ private:
+  // Event to notify when a resolve request was received.
+  base::WaitableEvent event_;
+  bool was_request_cancelled_;
+};
+
+// This implementation of ProxyResolver simply does a synchronous resolve
+// on |host_resolver| in response to GetProxyForURL().
+class SyncProxyResolver : public ProxyResolver {
+ public:
+  explicit SyncProxyResolver(SyncHostResolverBridge* host_resolver)
+      : ProxyResolver(false), host_resolver_(host_resolver) {}
+
+  virtual int GetProxyForURL(const GURL& url,
+                             ProxyInfo* results,
+                             const CompletionCallback& callback,
+                             RequestHandle* request,
+                             const BoundNetLog& net_log) {
+    EXPECT_FALSE(!callback.is_null());
+    EXPECT_FALSE(request);
+
+    // Do a synchronous host resolve.
+    HostResolver::RequestInfo info(HostPortPair::FromURL(url));
+    AddressList addresses;
+    int rv = host_resolver_->Resolve(info, &addresses, net_log);
+
+    EXPECT_EQ(ERR_ABORTED, rv);
+
+    return rv;
+  }
+
+  virtual void CancelRequest(RequestHandle request) OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual LoadState GetLoadStateThreadSafe(
+      RequestHandle request) const OVERRIDE {
+    NOTREACHED();
+    return LOAD_STATE_IDLE;
+  }
+
+  virtual void Shutdown() OVERRIDE {
+    host_resolver_->Shutdown();
+  }
+
+  virtual void CancelSetPacScript() OVERRIDE {
+    NOTREACHED();
+  }
+
+  virtual int SetPacScript(
+      const scoped_refptr<ProxyResolverScriptData>& script_data,
+      const CompletionCallback& callback) OVERRIDE {
+    return OK;
+  }
+
+ private:
+  SyncHostResolverBridge* const host_resolver_;
+};
+
+class SyncProxyResolverFactory : public ProxyResolverFactory {
+ public:
+  // Takes ownership of |sync_host_resolver|.
+  explicit SyncProxyResolverFactory(SyncHostResolverBridge* sync_host_resolver)
+      : ProxyResolverFactory(false),
+        sync_host_resolver_(sync_host_resolver) {
+  }
+
+  virtual ProxyResolver* CreateProxyResolver() OVERRIDE {
+    return new SyncProxyResolver(sync_host_resolver_.get());
+  }
+
+ private:
+  const scoped_ptr<SyncHostResolverBridge> sync_host_resolver_;
+};
+
+// This helper thread is used to create the circumstances for the deadlock.
+// It is analagous to the "IO thread" which would be main thread running the
+// network stack.
+class IOThread : public base::Thread {
+ public:
+  IOThread() : base::Thread("IO-thread") {}
+
+  virtual ~IOThread() {
+    Stop();
+  }
+
+  BlockableHostResolver* async_resolver() {
+    return async_resolver_.get();
+  }
+
+ protected:
+  virtual void Init() OVERRIDE {
+    async_resolver_.reset(new BlockableHostResolver());
+
+    // Create a synchronous host resolver that operates the async host
+    // resolver on THIS thread.
+    SyncHostResolverBridge* sync_resolver =
+        new SyncHostResolverBridge(async_resolver_.get(), message_loop());
+
+    proxy_resolver_.reset(
+        new MultiThreadedProxyResolver(
+            new SyncProxyResolverFactory(sync_resolver),
+            1u));
+
+    // Initialize the resolver.
+    TestCompletionCallback callback;
+    proxy_resolver_->SetPacScript(ProxyResolverScriptData::FromURL(GURL()),
+                                  callback.callback());
+    EXPECT_EQ(OK, callback.WaitForResult());
+
+    // Start an asynchronous request to the proxy resolver
+    // (note that it will never complete).
+    proxy_resolver_->GetProxyForURL(
+        GURL("http://test/"), &results_, callback_.callback(), &request_,
+        BoundNetLog());
+  }
+
+  virtual void CleanUp() OVERRIDE {
+    // Cancel the outstanding request (note however that this will not
+    // unblock the PAC thread though).
+    proxy_resolver_->CancelRequest(request_);
+
+    // Delete the single threaded proxy resolver.
+    proxy_resolver_.reset();
+
+    // (There may have been a completion posted back to origin thread, avoid
+    // leaking it by running).
+    MessageLoop::current()->RunUntilIdle();
+
+    // During the teardown sequence of the single threaded proxy resolver,
+    // the outstanding host resolve should have been cancelled.
+    EXPECT_TRUE(async_resolver_->was_request_cancelled());
+  }
+
+ private:
+  // This (async) host resolver will outlive the thread that is operating it
+  // synchronously.
+  scoped_ptr<BlockableHostResolver> async_resolver_;
+
+  scoped_ptr<ProxyResolver> proxy_resolver_;
+
+  // Data for the outstanding request to the single threaded proxy resolver.
+  TestCompletionCallback callback_;
+  ProxyInfo results_;
+  ProxyResolver::RequestHandle request_;
+};
+
+// Test that a deadlock does not happen during shutdown when a host resolve
+// is outstanding on the SyncHostResolverBridge.
+// This is a regression test for http://crbug.com/41244.
+TEST(MultiThreadedProxyResolverTest, ShutdownIsCalledBeforeThreadJoin) {
+  IOThread io_thread;
+  base::Thread::Options options;
+  options.message_loop_type = MessageLoop::TYPE_IO;
+  ASSERT_TRUE(io_thread.StartWithOptions(options));
+
+  io_thread.async_resolver()->WaitUntilRequestIsReceived();
+
+  // Now upon exitting this scope, the IOThread is destroyed -- this will
+  // stop the IOThread, which will in turn delete the
+  // SingleThreadedProxyResolver, which in turn will stop its internal
+  // PAC thread (which is currently blocked waiting on the host resolve which
+  // is running on IOThread).  The IOThread::Cleanup() will verify that after
+  // the PAC thread is stopped, it cancels the request on the HostResolver.
+}
+
+}  // namespace
+
+}  // namespace net
